예제 #1
0
 private ulong UnsignedArithmetic(DataOpcode opcode, ulong left, ulong right)
 {
     ulong result = 0ul;
     switch (opcode)
     {
         case DataOpcode.MOV:
             break;
         case DataOpcode.ADD:
         case DataOpcode.ADDL:
             result = left + right;
             break;
         case DataOpcode.SUB:
         case DataOpcode.SUBL:
             result = left - right;
             break;
         case DataOpcode.MULT:
         case DataOpcode.MULTL:
             result = left * right;
             break;
         case DataOpcode.DIV:
         case DataOpcode.DIVL:
             result = left / right;
             break;
         case DataOpcode.MOD:
         case DataOpcode.MODL:
             result = left % right;
             break;
         case DataOpcode.INV:
         case DataOpcode.INVL:
             throw new ArgumentException("can't invert an unsigned number"); //maybe use something other than ArgumentException
         case DataOpcode.EQ:
         case DataOpcode.EQL:
             result = left == right ? 1UL : 0UL;
             break;
         case DataOpcode.INEQ:
         case DataOpcode.INEQL:
             result = left == right ? 0UL : 1UL;
             break;
         case DataOpcode.LT:
         case DataOpcode.LTL:
             result = left < right ? 1UL : 0UL;
             break;
         case DataOpcode.GT:
         case DataOpcode.GTL:
             result = left > right ? 1UL : 0UL;
             break;
         case DataOpcode.LTEQ:
         case DataOpcode.LTEQL:
             result = left > right ? 0UL : 1UL;
             break;
         case DataOpcode.GTEQ:
         case DataOpcode.GTEQL:
             result = left < right ? 0UL : 1UL;
             break;
         case DataOpcode.AND:
         case DataOpcode.ANDL:
             result = (left != 0UL && right != 0UL) ? 1UL : 0UL;
             break;
         case DataOpcode.OR:
         case DataOpcode.ORL:
             result = (left != 0UL && right != 0UL) ? 1UL : 0UL;
             break;
         case DataOpcode.NOT:
         case DataOpcode.NOTL:
             result = (left != 0UL) ? 0UL : 1UL;
             break;
         case DataOpcode.BWNOT:
         case DataOpcode.BWNOTL:
             result = ~left;
             break;
         case DataOpcode.BWAND:
         case DataOpcode.BWANDL:
             result = left & right;
             break;
         case DataOpcode.BWOR:
         case DataOpcode.BWORL:
             result = left | right;
             break;
         case DataOpcode.BWXOR:
         case DataOpcode.BWXORL:
             result = left ^ right;
             break;
         case DataOpcode.BWLSHIFT:
         case DataOpcode.BWLSHIFTL:
             result = left << (int)right; // max 63 bits
             break;
         case DataOpcode.BWRSHIFT:
         case DataOpcode.BWRSHIFTL:
             result = left >> (int)right;
             break;
         case DataOpcode.PUSH:
             break;
         case DataOpcode.POP:
             break;
         case DataOpcode.PEEK:
             break;
         case DataOpcode.STACKALLOC:
             break;
         case DataOpcode.ARRAYALLOC:
             break;
         case DataOpcode.DEREF:
             break;
         case DataOpcode.ARRAYACCESS:
             break;
         case DataOpcode.CBYTE:
             break;
         case DataOpcode.CSBYTE:
             break;
         case DataOpcode.CSHORT:
             break;
         case DataOpcode.CUSHORT:
             break;
         case DataOpcode.CINT:
             break;
         case DataOpcode.CUINT:
             break;
         case DataOpcode.CLONG:
             break;
         case DataOpcode.CULONG:
             break;
         case DataOpcode.CSING:
             break;
         case DataOpcode.CDOUBLE:
             break;
         default:
             break;
     }
     return result;
 }
예제 #2
0
        private void LongArithmeticInstruction(DataOpcode opcode, Operand left, Operand right, Operand dest)
        {
            if (left.Type == Operand.OperandType.LPString || right.Type == Operand.OperandType.LPString)
            {
                throw new ArgumentException("can't do arithmetic on strings");
            }
            if (dest.Type != Operand.OperandType.AddressBlock && dest.Type != Operand.OperandType.Register && dest.Type != Operand.OperandType.StackIndex)
            {
                throw new ArgumentException("can't assign to a literal");
            }

            ByteBlock op1 = GetValue(left);
            ByteBlock op2 = GetValue(right);

            ulong uresult;
            long sresult;
            double fresult;
            ByteBlock result;
            if ((left.Type == Operand.OperandType.NumericByte || left.Type == Operand.OperandType.NumericUShort ||
                 left.Type == Operand.OperandType.NumericUInt || left.Type == Operand.OperandType.NumericULong ||
                 left.Type == Operand.OperandType.Register || left.Type == Operand.OperandType.AddressBlock) &&
                (right.Type == Operand.OperandType.NumericByte || right.Type == Operand.OperandType.NumericUShort ||
                 right.Type == Operand.OperandType.NumericUInt || right.Type == Operand.OperandType.NumericULong ||
                 right.Type == Operand.OperandType.Register || right.Type == Operand.OperandType.AddressBlock)) // for now, register & memory values are only treated as ulongs.  Fix
            {
                uresult = UnsignedArithmetic(opcode, op1.ToULong(), op2.ToULong());
                if (dest.Type == Operand.OperandType.Register)
                {
                    result = new ByteBlock(uresult);
                    WriteRegister((byte)dest.Value, result);
                }
                else
                {
                //	this.Memory.WriteULongAt(uresult, (int)(((AddressBlock)dest.Value).Address)); fix
                }
            }
            else if ((left.Type == Operand.OperandType.NumericSByte || left.Type == Operand.OperandType.NumericShort ||
                      left.Type == Operand.OperandType.NumericInt || left.Type == Operand.OperandType.NumericLong) &&
                     (right.Type == Operand.OperandType.NumericSByte || right.Type == Operand.OperandType.NumericShort ||
                      right.Type == Operand.OperandType.NumericInt || right.Type == Operand.OperandType.NumericLong))
            {
                sresult = SignedArithmetic(opcode, op1.ToLong(), op2.ToLong());
                if (dest.Type == Operand.OperandType.Register)
                {
                    result = new ByteBlock(sresult);
                    WriteRegister((byte)dest.Value, result);
                }
                else
                {
                //	this.Memory.WriteLongAt(sresult, (int)(((AddressBlock)dest.Value).Address)); fix
                }
            }
            else
            {
                fresult = FPArithmetic(opcode, op1.ToDouble(), op2.ToDouble());
                if (dest.Type == Operand.OperandType.Register)
                {
                    result = new ByteBlock(fresult);
                    WriteRegister((byte)dest.Value, result);
                }
                else
                {
                //	this.Memory.WriteDoubleAt(fresult, (int)(((AddressBlock)dest.Value).Address)); fix
                }
            }
        }
예제 #3
0
 // I don't like this repetition
 private long SignedArithmetic(DataOpcode opcode, long left, long right)
 {
     long result = 0L;
     switch (opcode)
     {
         case DataOpcode.MOV:
             break;
         case DataOpcode.ADD:
         case DataOpcode.ADDL:
             result = left + right;
             break;
         case DataOpcode.SUB:
         case DataOpcode.SUBL:
             result = left - right;
             break;
         case DataOpcode.MULT:
         case DataOpcode.MULTL:
             result = left * right;
             break;
         case DataOpcode.DIV:
         case DataOpcode.DIVL:
             result = left / right;
             break;
         case DataOpcode.MOD:
         case DataOpcode.MODL:
             result = left % right;
             break;
         case DataOpcode.INV:
         case DataOpcode.INVL:
             result = -left;
             break;
         case DataOpcode.EQ:
         case DataOpcode.EQL:
             result = left == right ? 1L : 0L;
             break;
         case DataOpcode.INEQ:
         case DataOpcode.INEQL:
             result = left == right ? 0L : 1L;
             break;
         case DataOpcode.LT:
         case DataOpcode.LTL:
             result = left < right ? 1L : 0L;
             break;
         case DataOpcode.GT:
         case DataOpcode.GTL:
             result = left > right ? 1L : 0L;
             break;
         case DataOpcode.LTEQ:
         case DataOpcode.LTEQL:
             result = left > right ? 0L : 1L;
             break;
         case DataOpcode.GTEQ:
         case DataOpcode.GTEQL:
             result = left < right ? 0L : 1L;
             break;
         case DataOpcode.AND:
         case DataOpcode.ANDL:
             result = (left != 0L && right != 0L) ? 1L : 0L;
             break;
         case DataOpcode.OR:
         case DataOpcode.ORL:
             result = (left != 0L && right != 0L) ? 1L : 0L;
             break;
         case DataOpcode.NOT:
         case DataOpcode.NOTL:
             result = (left != 0L) ? 0L : 1L;
             break;
         case DataOpcode.BWNOT:
         case DataOpcode.BWNOTL:
             result = ~left;
             break;
         case DataOpcode.BWAND:
         case DataOpcode.BWANDL:
             result = left & right;
             break;
         case DataOpcode.BWOR:
         case DataOpcode.BWORL:
             result = left | right;
             break;
         case DataOpcode.BWXOR:
         case DataOpcode.BWXORL:
             result = left ^ right;
             break;
         case DataOpcode.BWLSHIFT:
         case DataOpcode.BWLSHIFTL:
             result = left << (int)right; // max 63 bits
             break;
         case DataOpcode.BWRSHIFT:
         case DataOpcode.BWRSHIFTL:
             result = left >> (int)right;
             break;
         case DataOpcode.PUSH:
             break;
         case DataOpcode.POP:
             break;
         case DataOpcode.PEEK:
             break;
         case DataOpcode.STACKALLOC:
             break;
         case DataOpcode.ARRAYALLOC:
             break;
         case DataOpcode.DEREF:
             break;
         case DataOpcode.ARRAYACCESS:
             break;
         case DataOpcode.CBYTE:
             break;
         case DataOpcode.CSBYTE:
             break;
         case DataOpcode.CSHORT:
             break;
         case DataOpcode.CUSHORT:
             break;
         case DataOpcode.CINT:
             break;
         case DataOpcode.CUINT:
             break;
         case DataOpcode.CLONG:
             break;
         case DataOpcode.CULONG:
             break;
         case DataOpcode.CSING:
             break;
         case DataOpcode.CDOUBLE:
             break;
         default:
             break;
     }
     return result;
 }
예제 #4
0
 private double FPArithmetic(DataOpcode opcode, double left, double right)
 {
     double result = 0d;
     switch (opcode)
     {
         case DataOpcode.MOV:
             break;
         case DataOpcode.ADD:
         case DataOpcode.ADDL:
             result = left + right;
             break;
         case DataOpcode.SUB:
         case DataOpcode.SUBL:
             result = left - right;
             break;
         case DataOpcode.MULT:
         case DataOpcode.MULTL:
             result = left * right;
             break;
         case DataOpcode.DIV:
         case DataOpcode.DIVL:
             result = left / right;
             break;
         case DataOpcode.MOD:
         case DataOpcode.MODL:
             result = left % right;
             break;
         case DataOpcode.INV:
         case DataOpcode.INVL:
             result = -left;
             break;
         case DataOpcode.EQ:
         case DataOpcode.EQL:
             result = left == right ? 1.0 : 0.0;
             break;
         case DataOpcode.INEQ:
         case DataOpcode.INEQL:
             result = left == right ? 0.0 : 1.0;
             break;
         case DataOpcode.LT:
         case DataOpcode.LTL:
             result = left < right ? 1.0 : 0.0;
             break;
         case DataOpcode.GT:
         case DataOpcode.GTL:
             result = left > right ? 1.0 : 0.0;
             break;
         case DataOpcode.LTEQ:
         case DataOpcode.LTEQL:
             result = left > right ? 0.0 : 1.0;
             break;
         case DataOpcode.GTEQ:
         case DataOpcode.GTEQL:
             result = left < right ? 0.0 : 1.0;
             break;
         case DataOpcode.AND:
         case DataOpcode.ANDL:
             result = (left != 0.0 && right != 0.0) ? 1.0 : 0.0;
             break;
         case DataOpcode.OR:
         case DataOpcode.ORL:
             result = (left != 0.0 && right != 0.0) ? 1.0 : 0.0;
             break;
         case DataOpcode.NOT:
         case DataOpcode.NOTL:
             result = (left != 0.0) ? 0.0 : 1.0;
             break;
         case DataOpcode.BWNOT:
         case DataOpcode.BWNOTL:
         case DataOpcode.BWAND:
         case DataOpcode.BWANDL:
         case DataOpcode.BWOR:
         case DataOpcode.BWORL:
         case DataOpcode.BWXOR:
         case DataOpcode.BWXORL:
         case DataOpcode.BWLSHIFT:
         case DataOpcode.BWLSHIFTL:
         case DataOpcode.BWRSHIFT:
         case DataOpcode.BWRSHIFTL:
             throw new ArgumentException("can't do Boolean operations on floating-point values");
         case DataOpcode.PUSH:
             break;
         case DataOpcode.POP:
             break;
         case DataOpcode.PEEK:
             break;
         case DataOpcode.STACKALLOC:
             break;
         case DataOpcode.ARRAYALLOC:
             break;
         case DataOpcode.DEREF:
             break;
         case DataOpcode.ARRAYACCESS:
             break;
         case DataOpcode.CBYTE:
             break;
         case DataOpcode.CSBYTE:
             break;
         case DataOpcode.CSHORT:
             break;
         case DataOpcode.CUSHORT:
             break;
         case DataOpcode.CINT:
             break;
         case DataOpcode.CUINT:
             break;
         case DataOpcode.CLONG:
             break;
         case DataOpcode.CULONG:
             break;
         case DataOpcode.CSING:
             break;
         case DataOpcode.CDOUBLE:
             break;
         default:
             break;
     }
     return result;
 }