Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2011 Christoph Bumiller
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice shall be included in
  12.  * all copies or substantial portions of the Software.
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20.  * OTHER DEALINGS IN THE SOFTWARE.
  21.  */
  22.  
  23. #ifndef __NV50_IR_INLINES_H__
  24. #define __NV50_IR_INLINES_H__
  25.  
  26. static inline CondCode reverseCondCode(CondCode cc)
  27. {
  28.    static const uint8_t ccRev[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
  29.  
  30.    return static_cast<CondCode>(ccRev[cc & 7] | (cc & ~7));
  31. }
  32.  
  33. static inline CondCode inverseCondCode(CondCode cc)
  34. {
  35.    return static_cast<CondCode>(cc ^ 7);
  36. }
  37.  
  38. static inline bool isMemoryFile(DataFile f)
  39. {
  40.    return (f >= FILE_MEMORY_CONST && f <= FILE_MEMORY_LOCAL);
  41. }
  42.  
  43. // contrary to asTex(), this will never include SULD/SUST
  44. static inline bool isTextureOp(operation op)
  45. {
  46.    return (op >= OP_TEX && op <= OP_TEXPREP);
  47. }
  48.  
  49. static inline bool isSurfaceOp(operation op)
  50. {
  51.    return (op >= OP_SULDB && op <= OP_SULEA);
  52. }
  53.  
  54. static inline unsigned int typeSizeof(DataType ty)
  55. {
  56.    switch (ty) {
  57.    case TYPE_U8:
  58.    case TYPE_S8:
  59.       return 1;
  60.    case TYPE_F16:
  61.    case TYPE_U16:
  62.    case TYPE_S16:
  63.       return 2;
  64.    case TYPE_F32:
  65.    case TYPE_U32:
  66.    case TYPE_S32:
  67.       return 4;
  68.    case TYPE_F64:
  69.    case TYPE_U64:
  70.    case TYPE_S64:
  71.       return 8;
  72.    case TYPE_B96:
  73.       return 12;
  74.    case TYPE_B128:
  75.       return 16;
  76.    default:
  77.       return 0;
  78.    }
  79. }
  80.  
  81. static inline unsigned int typeSizeofLog2(DataType ty)
  82. {
  83.    switch (ty) {
  84.    case TYPE_F16:
  85.    case TYPE_U16:
  86.    case TYPE_S16:
  87.       return 1;
  88.    case TYPE_F32:
  89.    case TYPE_U32:
  90.    case TYPE_S32:
  91.       return 2;
  92.    case TYPE_F64:
  93.    case TYPE_U64:
  94.    case TYPE_S64:
  95.       return 3;
  96.    case TYPE_B96:
  97.    case TYPE_B128:
  98.       return 4;
  99.    case TYPE_U8:
  100.    case TYPE_S8:
  101.    default:
  102.       return 0;
  103.    }
  104. }
  105.  
  106. static inline DataType typeOfSize(unsigned int size,
  107.                                   bool flt = false, bool sgn = false)
  108. {
  109.    switch (size) {
  110.    case 1: return sgn ? TYPE_S8 : TYPE_U8;
  111.    case 2: return flt ? TYPE_F16 : (sgn ? TYPE_S16 : TYPE_U16);
  112.    case 8: return flt ? TYPE_F64 : (sgn ? TYPE_S64 : TYPE_U64);
  113.    case 12: return TYPE_B96;
  114.    case 16: return TYPE_B128;
  115.    case 4:
  116.       return flt ? TYPE_F32 : (sgn ? TYPE_S32 : TYPE_U32);
  117.    default:
  118.       return TYPE_NONE;
  119.    }
  120. }
  121.  
  122. static inline bool isFloatType(DataType ty)
  123. {
  124.    return (ty >= TYPE_F16 && ty <= TYPE_F64);
  125. }
  126.  
  127. static inline bool isSignedIntType(DataType ty)
  128. {
  129.    return (ty == TYPE_S8 || ty == TYPE_S16 || ty == TYPE_S32);
  130. }
  131.  
  132. static inline bool isSignedType(DataType ty)
  133. {
  134.    switch (ty) {
  135.    case TYPE_NONE:
  136.    case TYPE_U8:
  137.    case TYPE_U16:
  138.    case TYPE_U32:
  139.    case TYPE_B96:
  140.    case TYPE_B128:
  141.       return false;
  142.    default:
  143.       return true;
  144.    }
  145. }
  146.  
  147. static inline DataType intTypeToSigned(DataType ty)
  148. {
  149.    switch (ty) {
  150.    case TYPE_U32: return TYPE_S32;
  151.    case TYPE_U16: return TYPE_S16;
  152.    case TYPE_U8: return TYPE_S8;
  153.    default:
  154.       return ty;
  155.    }
  156. }
  157.  
  158. const ValueRef *ValueRef::getIndirect(int dim) const
  159. {
  160.    return isIndirect(dim) ? &insn->src(indirect[dim]) : NULL;
  161. }
  162.  
  163. DataFile ValueRef::getFile() const
  164. {
  165.    return value ? value->reg.file : FILE_NULL;
  166. }
  167.  
  168. unsigned int ValueRef::getSize() const
  169. {
  170.    return value ? value->reg.size : 0;
  171. }
  172.  
  173. Value *ValueRef::rep() const
  174. {
  175.    assert(value);
  176.    return value->join;
  177. }
  178.  
  179. Value *ValueDef::rep() const
  180. {
  181.    assert(value);
  182.    return value->join;
  183. }
  184.  
  185. DataFile ValueDef::getFile() const
  186. {
  187.    return value ? value->reg.file : FILE_NULL;
  188. }
  189.  
  190. unsigned int ValueDef::getSize() const
  191. {
  192.    return value ? value->reg.size : 0;
  193. }
  194.  
  195. void ValueDef::setSSA(LValue *lval)
  196. {
  197.    origin = value->asLValue();
  198.    set(lval);
  199. }
  200.  
  201. const LValue *ValueDef::preSSA() const
  202. {
  203.    return origin;
  204. }
  205.  
  206. Instruction *Value::getInsn() const
  207. {
  208.    return defs.empty() ? NULL : defs.front()->getInsn();
  209. }
  210.  
  211. Instruction *Value::getUniqueInsn() const
  212. {
  213.    if (defs.empty())
  214.       return NULL;
  215.  
  216.    // after regalloc, the definitions of coalesced values are linked
  217.    if (join != this) {
  218.       for (DefCIterator it = defs.begin(); it != defs.end(); ++it)
  219.          if ((*it)->get() == this)
  220.             return (*it)->getInsn();
  221.       // should be unreachable and trigger assertion at the end
  222.    }
  223. #ifdef DEBUG
  224.    if (reg.data.id < 0) {
  225.       int n = 0;
  226.       for (DefCIterator it = defs.begin(); n < 2 && it != defs.end(); ++it)
  227.          if ((*it)->get() == this) // don't count joined values
  228.             ++n;
  229.       if (n > 1)
  230.          WARN("value %%%i not uniquely defined\n", id); // return NULL ?
  231.    }
  232. #endif
  233.    assert(defs.front()->get() == this);
  234.    return defs.front()->getInsn();
  235. }
  236.  
  237. inline bool Instruction::constrainedDefs() const
  238. {
  239.    return defExists(1) || op == OP_UNION;
  240. }
  241.  
  242. Value *Instruction::getIndirect(int s, int dim) const
  243. {
  244.    return srcs[s].isIndirect(dim) ? getSrc(srcs[s].indirect[dim]) : NULL;
  245. }
  246.  
  247. Value *Instruction::getPredicate() const
  248. {
  249.    return (predSrc >= 0) ? getSrc(predSrc) : NULL;
  250. }
  251.  
  252. void Instruction::setFlagsDef(int d, Value *val)
  253. {
  254.    if (val) {
  255.       if (flagsDef < 0)
  256.          flagsDef = d;
  257.       setDef(flagsDef, val);
  258.    } else {
  259.       if (flagsDef >= 0) {
  260.          setDef(flagsDef, NULL);
  261.          flagsDef = -1;
  262.       }
  263.    }
  264. }
  265.  
  266. void Instruction::setFlagsSrc(int s, Value *val)
  267. {
  268.    flagsSrc = s;
  269.    setSrc(flagsSrc, val);
  270. }
  271.  
  272. Value *TexInstruction::getIndirectR() const
  273. {
  274.    return tex.rIndirectSrc >= 0 ? getSrc(tex.rIndirectSrc) : NULL;
  275. }
  276.  
  277. Value *TexInstruction::getIndirectS() const
  278. {
  279.    return tex.rIndirectSrc >= 0 ? getSrc(tex.rIndirectSrc) : NULL;
  280. }
  281.  
  282. CmpInstruction *Instruction::asCmp()
  283. {
  284.    if (op >= OP_SET_AND && op <= OP_SLCT && op != OP_SELP)
  285.       return static_cast<CmpInstruction *>(this);
  286.    return NULL;
  287. }
  288.  
  289. const CmpInstruction *Instruction::asCmp() const
  290. {
  291.    if (op >= OP_SET_AND && op <= OP_SLCT && op != OP_SELP)
  292.       return static_cast<const CmpInstruction *>(this);
  293.    return NULL;
  294. }
  295.  
  296. FlowInstruction *Instruction::asFlow()
  297. {
  298.    if (op >= OP_BRA && op <= OP_JOIN)
  299.       return static_cast<FlowInstruction *>(this);
  300.    return NULL;
  301. }
  302.  
  303. const FlowInstruction *Instruction::asFlow() const
  304. {
  305.    if (op >= OP_BRA && op <= OP_JOIN)
  306.       return static_cast<const FlowInstruction *>(this);
  307.    return NULL;
  308. }
  309.  
  310. TexInstruction *Instruction::asTex()
  311. {
  312.    if (op >= OP_TEX && op <= OP_SULEA)
  313.       return static_cast<TexInstruction *>(this);
  314.    return NULL;
  315. }
  316.  
  317. const TexInstruction *Instruction::asTex() const
  318. {
  319.    if (op >= OP_TEX && op <= OP_SULEA)
  320.       return static_cast<const TexInstruction *>(this);
  321.    return NULL;
  322. }
  323.  
  324. static inline Instruction *cloneForward(Function *ctx, Instruction *obj)
  325. {
  326.    DeepClonePolicy<Function> pol(ctx);
  327.  
  328.    for (int i = 0; obj->srcExists(i); ++i)
  329.       pol.set(obj->getSrc(i), obj->getSrc(i));
  330.  
  331.    return obj->clone(pol);
  332. }
  333.  
  334. // XXX: use a virtual function so we're really really safe ?
  335. LValue *Value::asLValue()
  336. {
  337.    if (reg.file >= FILE_GPR && reg.file <= FILE_ADDRESS)
  338.       return static_cast<LValue *>(this);
  339.    return NULL;
  340. }
  341.  
  342. Symbol *Value::asSym()
  343. {
  344.    if (reg.file >= FILE_MEMORY_CONST)
  345.       return static_cast<Symbol *>(this);
  346.    return NULL;
  347. }
  348.  
  349. const Symbol *Value::asSym() const
  350. {
  351.    if (reg.file >= FILE_MEMORY_CONST)
  352.       return static_cast<const Symbol *>(this);
  353.    return NULL;
  354. }
  355.  
  356. void Symbol::setOffset(int32_t offset)
  357. {
  358.    reg.data.offset = offset;
  359. }
  360.  
  361. void Symbol::setAddress(Symbol *base, int32_t offset)
  362. {
  363.    baseSym = base;
  364.    reg.data.offset = offset;
  365. }
  366.  
  367. void Symbol::setSV(SVSemantic sv, uint32_t index)
  368. {
  369.    reg.data.sv.sv = sv;
  370.    reg.data.sv.index = index;
  371. }
  372.  
  373. ImmediateValue *Value::asImm()
  374. {
  375.    if (reg.file == FILE_IMMEDIATE)
  376.       return static_cast<ImmediateValue *>(this);
  377.    return NULL;
  378. }
  379.  
  380. const ImmediateValue *Value::asImm() const
  381. {
  382.    if (reg.file == FILE_IMMEDIATE)
  383.       return static_cast<const ImmediateValue *>(this);
  384.    return NULL;
  385. }
  386.  
  387. Value *Value::get(Iterator &it)
  388. {
  389.    return reinterpret_cast<Value *>(it.get());
  390. }
  391.  
  392. bool BasicBlock::reachableBy(const BasicBlock *by, const BasicBlock *term)
  393. {
  394.    return cfg.reachableBy(&by->cfg, &term->cfg);
  395. }
  396.  
  397. BasicBlock *BasicBlock::get(Iterator &iter)
  398. {
  399.    return reinterpret_cast<BasicBlock *>(iter.get());
  400. }
  401.  
  402. BasicBlock *BasicBlock::get(Graph::Node *node)
  403. {
  404.    assert(node);
  405.    return reinterpret_cast<BasicBlock *>(node->data);
  406. }
  407.  
  408. Function *Function::get(Graph::Node *node)
  409. {
  410.    assert(node);
  411.    return reinterpret_cast<Function *>(node->data);
  412. }
  413.  
  414. LValue *Function::getLValue(int id)
  415. {
  416.    assert((unsigned int)id < (unsigned int)allLValues.getSize());
  417.    return reinterpret_cast<LValue *>(allLValues.get(id));
  418. }
  419.  
  420. #endif // __NV50_IR_INLINES_H__
  421.