Exemple #1
0
 Instruction ParseBinOp(BinOpKind op)
 {
     DestRegister dst = ParseDestReg ();
     SrcRegister src1 = ParseSrcReg ();
     SrcRegister src2 = ParseSrcReg ();
     return new BinaryOp (op, dst, src1, src2);
 }
Exemple #2
0
 public BinaryOp(BinOpKind op, DestRegister dest, SrcRegister src1, SrcRegister src2)
 {
     this.op = op;
     this.dest = dest;
     this.src1 = src1;
     this.src2 = src2;
 }
Exemple #3
0
 internal void EmitBinary(BinOpKind op)
 {
     //FIXME if might be an issue if arguments are not of type Vector4f
     MethodInfo mi = null;
     switch (op) {
     case BinOpKind.Add:
         mi = typeof (Vector4f).GetMethod ("op_Addition");
         break;
     case BinOpKind.Mul:
         mi = typeof (Vector4f).GetMethod ("op_Multiply");
         break;
     default:
         throw new Exception ("can't handle binop " + op);
     }
     ilgen.Emit (OpCodes.Call, mi);
 }
Exemple #4
0
 /*
     Given a binary operator EXPRKIND, get the BinOpKind and flags.
 */
 private bool GetBinopKindAndFlags(ExpressionKind ek, out BinOpKind pBinopKind, out EXPRFLAG flags)
 {
     flags = 0;
     switch (ek)
     {
         case ExpressionKind.EK_ADD:
             if (Context.CheckedNormal)
             {
                 flags |= EXPRFLAG.EXF_CHECKOVERFLOW;
             }
             pBinopKind = BinOpKind.Add;
             break;
         case ExpressionKind.EK_SUB:
             if (Context.CheckedNormal)
             {
                 flags |= EXPRFLAG.EXF_CHECKOVERFLOW;
             }
             pBinopKind = BinOpKind.Sub;
             break;
         case ExpressionKind.EK_DIV:
         case ExpressionKind.EK_MOD:
             // EXPRKIND.EK_DIV and EXPRKIND.EK_MOD need to be treated special for hasSideEffects, 
             // hence the EXPRFLAG.EXF_ASSGOP. Yes, this is a hack.
             flags |= EXPRFLAG.EXF_ASSGOP;
             if (Context.CheckedNormal)
             {
                 flags |= EXPRFLAG.EXF_CHECKOVERFLOW;
             }
             pBinopKind = BinOpKind.Mul;
             break;
         case ExpressionKind.EK_MUL:
             if (Context.CheckedNormal)
             {
                 flags |= EXPRFLAG.EXF_CHECKOVERFLOW;
             }
             pBinopKind = BinOpKind.Mul;
             break;
         case ExpressionKind.EK_BITAND:
         case ExpressionKind.EK_BITOR:
             pBinopKind = BinOpKind.Bitwise;
             break;
         case ExpressionKind.EK_BITXOR:
             pBinopKind = BinOpKind.BitXor;
             break;
         case ExpressionKind.EK_LSHIFT:
         case ExpressionKind.EK_RSHIFT:
             pBinopKind = BinOpKind.Shift;
             break;
         case ExpressionKind.EK_LOGOR:
         case ExpressionKind.EK_LOGAND:
             pBinopKind = BinOpKind.Logical;
             break;
         case ExpressionKind.EK_LT:
         case ExpressionKind.EK_LE:
         case ExpressionKind.EK_GT:
         case ExpressionKind.EK_GE:
             pBinopKind = BinOpKind.Compare;
             break;
         case ExpressionKind.EK_EQ:
         case ExpressionKind.EK_NE:
             pBinopKind = BinOpKind.Equal;
             break;
         default:
             VSFAIL("Bad ek");
             pBinopKind = BinOpKind.Add;
             return false;
     }
     return true;
 }
Exemple #5
0
        internal void EmitBinary(BinOpKind op)
        {
            //FIXME it might be an issue if arguments are not of type Vector4f
            MethodInfo mi = null;
            switch (op) {
            case BinOpKind.Add:
                mi = typeof (Vector4f).GetMethod ("op_Addition");
                break;
            case BinOpKind.Sub:
                mi = typeof (Vector4f).GetMethod ("op_Subtraction");
                break;
            case BinOpKind.Mul:
                mi = typeof (Vector4f).GetMethod ("op_Multiply");
                break;
            case BinOpKind.Max:
                mi = typeof (VectorOperations).GetMethod ("Max", new Type[] { typeof (Vector4f), typeof (Vector4f)});
                break;
            case BinOpKind.Dp3:
                //This is a very f**k'd up code sequence, figure out how to speed it up
                ilgen.Emit (OpCodes.Call, typeof (Vector4f).GetMethod ("op_Multiply"));
                ilgen.Emit (OpCodes.Dup);
                ilgen.Emit (OpCodes.Dup);
                //FIXME we could use HorizontalAdd for this step
                EmitShuffle (ShuffleSel.XFromY); //[x,y,z,w] [x,y,z,w] [y,y,z,w]
                ilgen.Emit (OpCodes.Call, typeof (Vector4f).GetMethod ("op_Addition")); //[x,y,z,w] [x + y,_,_,_]

                EmitShuffle (ShuffleSel.ZFromY); //[x,y,z,w] [_,_,x + y, _]
                ilgen.Emit (OpCodes.Call, typeof (Vector4f).GetMethod ("op_Addition")); //[_,_, x + y + z, _]
                EmitShuffle (ShuffleSel.ExpandZ); //[dp3, dp3, dp3, dp3]
                break;
            case BinOpKind.Dp4:
                //We should use things like HorizontalAdd  or the new Dp instruction
                ilgen.Emit (OpCodes.Call, typeof (Vector4f).GetMethod ("op_Multiply"));
                ilgen.Emit (OpCodes.Dup);

                EmitShuffle (ShuffleSel.XFromY | ShuffleSel.ZFromW); //[x,y,z,w] [y,y,w,w]
                ilgen.Emit (OpCodes.Call, typeof (Vector4f).GetMethod ("op_Addition")); //[x + y,_,z + w,_]
                ilgen.Emit (OpCodes.Dup); //[x + y,_,z + w,_] [x + y,_,z + w,_]

                EmitShuffle (ShuffleSel.XFromZ); //[x + y,_,_,_] [z + w,_,_,_]
                ilgen.Emit (OpCodes.Call, typeof (Vector4f).GetMethod ("op_Addition")); //[x + y + z + w,_,_,_]
                EmitShuffle (ShuffleSel.ExpandX); //[dp4, dp4, dp4, dp4]
                break;
            case BinOpKind.Min:
                mi = typeof (VectorOperations).GetMethod ("Min", new Type[] { typeof (Vector4f), typeof (Vector4f)});
                break;
            case BinOpKind.Slt:
            case BinOpKind.Sge:
                //XXX hoist the constant out of the loop
                mi = typeof (VectorOperations).GetMethod ("CompareLessThan", new Type[] { typeof (Vector4f), typeof (Vector4f)});
                ilgen.Emit (OpCodes.Ldc_R4, 1f);
                ilgen.Emit (OpCodes.Call, typeof (Vector4f).GetConstructor (new Type [] {typeof (float) }));
                if (op == BinOpKind.Slt)
                    ilgen.Emit (OpCodes.Call, typeof (Vector4f).GetMethod ("op_BitwiseAnd"));
                else
                    ilgen.Emit (OpCodes.Call, typeof (VectorOperations).GetMethod ("AndNot", new Type[] { typeof (Vector4f), typeof (Vector4f)}));
                break;
            default:
                throw new Exception ("can't handle binop " + op);
            }
            if (mi != null)
                ilgen.Emit (OpCodes.Call, mi);
        }