changeset 7379:0cc86f2309be

Added DivRemOp that produces both the division result and the remainder.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 15 Jan 2013 18:27:01 +0100
parents 88506cfc3bab
children 3207ee96b659
files graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java
diffstat 1 files changed, 37 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Tue Jan 15 17:53:31 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Tue Jan 15 18:27:01 2013 +0100
@@ -35,8 +35,8 @@
 import com.oracle.graal.lir.asm.*;
 
 public enum AMD64Arithmetic {
-    IADD, ISUB, IMUL, IDIV, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR,
-    LADD, LSUB, LMUL, LDIV, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR,
+    IADD, ISUB, IMUL, IDIV, IDIVREM, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR,
+    LADD, LSUB, LMUL, LDIV, LDIVREM, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR,
     FADD, FSUB, FMUL, FDIV, FAND, FOR, FXOR,
     DADD, DSUB, DMUL, DDIV, DAND, DOR, DXOR,
     INEG, LNEG,
@@ -195,6 +195,39 @@
         }
     }
 
+    public static class DivRemOp extends AMD64LIRInstruction {
+        @Opcode private final AMD64Arithmetic opcode;
+        @Def protected Value divResult;
+        @Def protected Value remResult;
+        @Use protected Value x;
+        @Alive protected Value y;
+        @State protected LIRFrameState state;
+
+        public DivRemOp(AMD64Arithmetic opcode, Value x, Value y, LIRFrameState state) {
+            this.opcode = opcode;
+            this.divResult = AMD64.rax.asValue();
+            this.remResult = AMD64.rdx.asValue();
+            this.x = x;
+            this.y = y;
+            this.state = state;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            emit(tasm, masm, opcode, null, y, state);
+        }
+
+        @Override
+        protected void verify() {
+            super.verify();
+            // left input in rax, right input in any register but rax and rdx, result quotient in rax, result remainder in rdx
+            assert asRegister(x) == AMD64.rax;
+            assert differentRegisters(y, AMD64.rax.asValue(), AMD64.rdx.asValue());
+            verifyKind(opcode, divResult, x, y);
+            verifyKind(opcode, remResult, x, y);
+        }
+    }
+
     public static class DivOp extends AMD64LIRInstruction {
         @Opcode private final AMD64Arithmetic opcode;
         @Def protected Value result;
@@ -310,6 +343,7 @@
                 case MOV_F2I: masm.movdl(asIntReg(dst), asFloatReg(src)); break;
                 case MOV_D2L: masm.movdq(asLongReg(dst), asDoubleReg(src)); break;
 
+                case IDIVREM:
                 case IDIV:
                 case IREM:
                     masm.cdql();
@@ -317,6 +351,7 @@
                     masm.idivl(asRegister(src));
                     break;
 
+                case LDIVREM:
                 case LDIV:
                 case LREM:
                     masm.cdqq();