# HG changeset patch
# User Christian.Wimmer@Oracle.com
# Date 1305331760 25200
# Node ID 0ea5f12e873ac7f567574b1d2c13ab56f2442b52
# Parent e0e89714e2f18da9ed9fb85ca05be1b5a15b6c3c
use com.oracle.max.asm project for assembler
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/.classpath
--- a/graal/GraalCompiler/.classpath Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/.classpath Fri May 13 17:09:20 2011 -0700
@@ -1,9 +1,10 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java
--- a/graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java Fri May 13 17:09:20 2011 -0700
@@ -25,6 +25,7 @@
import java.util.*;
+import com.oracle.max.asm.*;
import com.oracle.graal.graph.*;
import com.sun.c1x.alloc.*;
import com.sun.c1x.asm.*;
@@ -41,8 +42,6 @@
/**
* This class encapsulates global information about the compilation of a particular method,
* including a reference to the runtime, statistics about the compiled code, etc.
- *
- * @author Ben L. Titzer
*/
public final class C1XCompilation {
@@ -71,7 +70,7 @@
private int nextID = 1;
private FrameMap frameMap;
- private AbstractAssembler assembler;
+ private TargetMethodAssembler assembler;
private IR hir;
@@ -187,9 +186,10 @@
return frameMap;
}
- public AbstractAssembler masm() {
+ public TargetMethodAssembler assembler() {
if (assembler == null) {
- assembler = compiler.backend.newAssembler(registerConfig);
+ AbstractAssembler asm = compiler.backend.newAssembler(registerConfig);
+ assembler = new TargetMethodAssembler(asm);
assembler.setFrameSize(frameMap.frameSize());
assembler.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea());
}
@@ -280,7 +280,7 @@
// generate traps at the end of the method
lirAssembler.emitTraps();
- CiTargetMethod targetMethod = masm().finishTargetMethod(method, runtime, lirAssembler.registerRestoreEpilogueOffset, false);
+ CiTargetMethod targetMethod = assembler().finishTargetMethod(method, runtime, lirAssembler.registerRestoreEpilogueOffset, false);
if (assumptions.count() > 0) {
targetMethod.setAssumptions(assumptions);
}
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/asm/AbstractAssembler.java
--- a/graal/GraalCompiler/src/com/sun/c1x/asm/AbstractAssembler.java Fri May 13 14:03:03 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,243 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.c1x.asm;
-
-import java.util.*;
-
-import com.sun.c1x.*;
-import com.sun.c1x.debug.*;
-import com.sun.c1x.ir.*;
-import com.sun.c1x.lir.*;
-import com.sun.c1x.util.*;
-import com.sun.cri.ci.*;
-import com.sun.cri.ci.CiTargetMethod.CodeComment;
-import com.sun.cri.ci.CiTargetMethod.Mark;
-import com.sun.cri.ri.*;
-
-/**
- * @author Marcelo Cintra
- * @author Thomas Wuerthinger
- */
-public abstract class AbstractAssembler {
-
- public final Buffer codeBuffer;
- public final CiTarget target;
- public final CiTargetMethod targetMethod;
- public List exceptionInfoList;
- protected int lastSafepointPos;
-
- public AbstractAssembler(CiTarget target) {
- this.target = target;
- this.targetMethod = new CiTargetMethod();
- this.codeBuffer = new Buffer(target.arch.byteOrder);
- }
-
- public final void bind(Label l) {
- assert !l.isBound() : "can bind label only once";
- l.bind(codeBuffer.position());
- l.patchInstructions(this);
- }
-
- public void setFrameSize(int frameSize) {
- targetMethod.setFrameSize(frameSize);
- }
-
- public CiTargetMethod finishTargetMethod(Object name, RiRuntime runtime, int registerRestoreEpilogueOffset, boolean isStub) {
- // Install code, data and frame size
- targetMethod.setTargetCode(codeBuffer.close(false), codeBuffer.position());
- targetMethod.setRegisterRestoreEpilogueOffset(registerRestoreEpilogueOffset);
-
- // Record exception handlers if they exist
- if (exceptionInfoList != null) {
- for (ExceptionInfo ei : exceptionInfoList) {
- int codeOffset = ei.codeOffset;
- for (ExceptionHandler handler : ei.exceptionHandlers) {
- int entryOffset = handler.entryCodeOffset();
- RiType caughtType = handler.handler.catchType();
- targetMethod.recordExceptionHandler(codeOffset, ei.bci, 0, entryOffset, handler.handlerBCI(), caughtType);
- }
- }
- }
-
- if (C1XOptions.PrintMetrics) {
- C1XMetrics.TargetMethods++;
- C1XMetrics.CodeBytesEmitted += targetMethod.targetCodeSize();
- C1XMetrics.SafepointsEmitted += targetMethod.safepoints.size();
- C1XMetrics.DirectCallSitesEmitted += targetMethod.directCalls.size();
- C1XMetrics.IndirectCallSitesEmitted += targetMethod.indirectCalls.size();
- C1XMetrics.DataPatches += targetMethod.dataReferences.size();
- C1XMetrics.ExceptionHandlersEmitted += targetMethod.exceptionHandlers.size();
- }
-
- if (C1XOptions.PrintAssembly && !TTY.isSuppressed() && !isStub) {
- Util.printSection("Target Method", Util.SECTION_CHARACTER);
- TTY.println("Name: " + name);
- TTY.println("Frame size: " + targetMethod.frameSize());
- TTY.println("Register size: " + target.arch.registerReferenceMapBitCount);
-
- if (C1XOptions.PrintCodeBytes) {
- Util.printSection("Code", Util.SUB_SECTION_CHARACTER);
- TTY.println("Code: %d bytes", targetMethod.targetCodeSize());
- Util.printBytes(0L, targetMethod.targetCode(), 0, targetMethod.targetCodeSize(), C1XOptions.PrintAssemblyBytesPerLine);
- }
-
- Util.printSection("Disassembly", Util.SUB_SECTION_CHARACTER);
- String disassembly = runtime.disassemble(targetMethod);
- TTY.println(disassembly);
- boolean noDis = disassembly == null || disassembly.length() == 0;
-
- Util.printSection("Safepoints", Util.SUB_SECTION_CHARACTER);
- for (CiTargetMethod.Safepoint x : targetMethod.safepoints) {
- TTY.println(x.toString());
- if (noDis && x.debugInfo != null) {
- TTY.println(CiUtil.indent(x.debugInfo.toString(), " "));
- }
- }
-
- Util.printSection("Direct Call Sites", Util.SUB_SECTION_CHARACTER);
- for (CiTargetMethod.Call x : targetMethod.directCalls) {
- TTY.println(x.toString());
- if (noDis && x.debugInfo != null) {
- TTY.println(CiUtil.indent(x.debugInfo.toString(), " "));
- }
- }
-
- Util.printSection("Indirect Call Sites", Util.SUB_SECTION_CHARACTER);
- for (CiTargetMethod.Call x : targetMethod.indirectCalls) {
- TTY.println(x.toString());
- if (noDis && x.debugInfo != null) {
- TTY.println(CiUtil.indent(x.debugInfo.toString(), " "));
- }
- }
-
- Util.printSection("Data Patches", Util.SUB_SECTION_CHARACTER);
- for (CiTargetMethod.DataPatch x : targetMethod.dataReferences) {
- TTY.println(x.toString());
- }
-
- Util.printSection("Marks", Util.SUB_SECTION_CHARACTER);
- for (CiTargetMethod.Mark x : targetMethod.marks) {
- TTY.println(x.toString());
- }
-
- Util.printSection("Exception Handlers", Util.SUB_SECTION_CHARACTER);
- for (CiTargetMethod.ExceptionHandler x : targetMethod.exceptionHandlers) {
- TTY.println(x.toString());
- }
- }
-
- return targetMethod;
- }
-
- public void recordExceptionHandlers(int pcOffset, LIRDebugInfo info) {
- if (info != null) {
- if (info.exceptionHandlers != null) {
- if (exceptionInfoList == null) {
- exceptionInfoList = new ArrayList(4);
- }
- exceptionInfoList.add(new ExceptionInfo(pcOffset, info.exceptionHandlers, info.state.bci));
- }
- }
- }
-
- public void recordImplicitException(int pcOffset, LIRDebugInfo info) {
- // record an implicit exception point
- if (info != null) {
- assert lastSafepointPos < pcOffset;
- lastSafepointPos = pcOffset;
- targetMethod.recordSafepoint(pcOffset, info.debugInfo());
- recordExceptionHandlers(pcOffset, info);
- }
- }
-
- protected void recordDirectCall(int posBefore, int posAfter, Object target, LIRDebugInfo info) {
- CiDebugInfo debugInfo = info != null ? info.debugInfo() : null;
- assert lastSafepointPos < posAfter;
- lastSafepointPos = posAfter;
- targetMethod.recordCall(posBefore, target, debugInfo, true);
- }
-
- protected void recordIndirectCall(int posBefore, int posAfter, Object target, LIRDebugInfo info) {
- CiDebugInfo debugInfo = info != null ? info.debugInfo() : null;
- assert lastSafepointPos < posAfter;
- lastSafepointPos = posAfter;
- targetMethod.recordCall(posBefore, target, debugInfo, false);
- }
-
- public void recordSafepoint(int pos, LIRDebugInfo info) {
- // safepoints always need debug info
- CiDebugInfo debugInfo = info.debugInfo();
- assert lastSafepointPos < pos;
- lastSafepointPos = pos;
- targetMethod.recordSafepoint(pos, debugInfo);
- }
-
- public CiAddress recordDataReferenceInCode(CiConstant data) {
- assert data != null;
-
- int pos = codeBuffer.position();
-
- if (C1XOptions.TraceRelocation) {
- TTY.print("Data reference in code: pos = %d, data = %s", pos, data.toString());
- }
-
- targetMethod.recordDataReference(pos, data);
- return CiAddress.Placeholder;
- }
-
- public Mark recordMark(Object id, Mark[] references) {
- return targetMethod.recordMark(codeBuffer.position(), id, references);
- }
-
- public abstract void nop();
-
- public abstract void nullCheck(CiRegister r);
-
- public abstract void align(int codeEntryAlignment);
-
- public abstract void patchJumpTarget(int branch, int target);
-
- public final void emitByte(int x) {
- codeBuffer.emitByte(x);
- }
-
- public final void emitShort(int x) {
- codeBuffer.emitShort(x);
- }
-
- public final void emitInt(int x) {
- codeBuffer.emitInt(x);
- }
-
- public final void emitLong(long x) {
- codeBuffer.emitLong(x);
- }
-
- public void blockComment(String s) {
- targetMethod.addAnnotation(new CodeComment(codeBuffer.position(), s));
- }
-
- public int lastSafepointPos() {
- return lastSafepointPos;
- }
-}
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/asm/Buffer.java
--- a/graal/GraalCompiler/src/com/sun/c1x/asm/Buffer.java Fri May 13 14:03:03 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,251 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.c1x.asm;
-
-import java.util.*;
-
-import com.sun.c1x.*;
-import com.sun.cri.bytecode.*;
-import com.sun.cri.ci.CiArchitecture.ByteOrder;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public final class Buffer {
-
- private byte[] data;
- private int position;
- private int mark = -1;
-
- private final ByteOrder byteOrder;
-
- public Buffer(ByteOrder byteOrder) {
- this.byteOrder = byteOrder;
- this.data = new byte[C1XOptions.InitialCodeBufferSize];
- }
-
- public void reset() {
- position = 0;
- mark = -1;
- }
-
- /**
- * Closes this buffer. No extra data can be written to this buffer after this call.
- *
- * @param trimmedCopy if {@code true}, then a copy of the underlying byte array up to (but not including)
- * {@code position()} is returned
- * @return the data in this buffer or a trimmed copy if {@code trimmedCopy} is {@code true}
- */
- public byte[] close(boolean trimmedCopy) {
- byte[] result = trimmedCopy ? Arrays.copyOf(data, position()) : data;
- data = null;
- return result;
- }
-
- public int emitBytes(byte[] arr, int off, int len) {
- assert data != null : "must not use buffer after calling finished!";
- int oldPos = position;
- ensureSize(position + len);
- System.arraycopy(arr, off, data, position, len);
- position += len;
- return oldPos;
- }
-
- public int emitByte(int b) {
- int oldPos = position;
- position = emitByte(b, oldPos);
- return oldPos;
- }
-
- public int emitShort(int b) {
- int oldPos = position;
- position = emitShort(b, oldPos);
- return oldPos;
- }
-
- public int emitInt(int b) {
- int oldPos = position;
- position = emitInt(b, oldPos);
- return oldPos;
- }
-
- public int emitLong(long b) {
- int oldPos = position;
- position = emitLong(b, oldPos);
- return oldPos;
- }
-
- private boolean isByte(int b) {
- return b == (b & 0xFF);
- }
-
- private boolean isShort(int s) {
- return s == (s & 0xFFFF);
- }
-
- /**
- * Places a bookmark at the {@linkplain #position() current position}.
- *
- * @return the previously placed bookmark or {@code -1} if there was no bookmark
- */
- public int mark() {
- int mark = this.mark;
- this.mark = position;
- return mark;
- }
-
- private void ensureSize(int length) {
- if (length >= data.length) {
- data = Arrays.copyOf(data, data.length * 4);
- C1XMetrics.CodeBufferCopies++;
- }
- }
-
- public int emitByte(int b, int pos) {
- assert data != null : "must not use buffer after calling finished!";
- assert isByte(b);
- ensureSize(pos + 1);
- data[pos++] = (byte) b;
- return pos;
- }
-
- public int emitShort(int b, int pos) {
- assert data != null : "must not use buffer after calling finished!";
- assert isShort(b);
- ensureSize(pos + 2);
- if (byteOrder == ByteOrder.BigEndian) {
- data[pos++] = (byte) ((b >> 8) & 0xFF);
- data[pos++] = (byte) (b & 0xFF);
-
- } else {
- assert byteOrder == ByteOrder.LittleEndian;
- data[pos++] = (byte) (b & 0xFF);
- data[pos++] = (byte) ((b >> 8) & 0xFF);
- }
- return pos;
- }
-
- public int emitInt(int b, int pos) {
- assert data != null : "must not use buffer after calling finished!";
- ensureSize(pos + 4);
- if (byteOrder == ByteOrder.BigEndian) {
- data[pos++] = (byte) ((b >> 24) & 0xFF);
- data[pos++] = (byte) ((b >> 16) & 0xFF);
- data[pos++] = (byte) ((b >> 8) & 0xFF);
- data[pos++] = (byte) (b & 0xFF);
- } else {
- assert byteOrder == ByteOrder.LittleEndian;
- data[pos++] = (byte) (b & 0xFF);
- data[pos++] = (byte) ((b >> 8) & 0xFF);
- data[pos++] = (byte) ((b >> 16) & 0xFF);
- data[pos++] = (byte) ((b >> 24) & 0xFF);
- }
- return pos;
- }
-
- public int emitLong(long b, int pos) {
- assert data != null : "must not use buffer after calling finished!";
- ensureSize(pos + 8);
-
- if (byteOrder == ByteOrder.BigEndian) {
- data[pos++] = (byte) ((b >> 56) & 0xFF);
- data[pos++] = (byte) ((b >> 48) & 0xFF);
- data[pos++] = (byte) ((b >> 40) & 0xFF);
- data[pos++] = (byte) ((b >> 32) & 0xFF);
- data[pos++] = (byte) ((b >> 24) & 0xFF);
- data[pos++] = (byte) ((b >> 16) & 0xFF);
- data[pos++] = (byte) ((b >> 8) & 0xFF);
- data[pos++] = (byte) (b & 0xFF);
- } else {
- assert byteOrder == ByteOrder.LittleEndian;
- data[pos++] = (byte) (b & 0xFF);
- data[pos++] = (byte) ((b >> 8) & 0xFF);
- data[pos++] = (byte) ((b >> 16) & 0xFF);
- data[pos++] = (byte) ((b >> 24) & 0xFF);
- data[pos++] = (byte) ((b >> 32) & 0xFF);
- data[pos++] = (byte) ((b >> 40) & 0xFF);
- data[pos++] = (byte) ((b >> 48) & 0xFF);
- data[pos++] = (byte) ((b >> 56) & 0xFF);
- }
- return pos;
- }
-
- public int position() {
- return position;
- }
-
- public void setPosition(int position) {
- assert position >= 0 && position <= data.length;
- this.position = position;
- }
-
- public int getByte(int pos) {
- return Bytes.beU1(data, pos);
- }
-
- public int getShort(int pos) {
- if (byteOrder == ByteOrder.BigEndian) {
- return
- (data[pos + 0] & 0xff) << 8 |
- (data[pos + 1] & 0xff) << 0;
- } else {
- assert byteOrder == ByteOrder.LittleEndian;
- return
- (data[pos + 1] & 0xff) << 8 |
- (data[pos + 0] & 0xff) << 0;
- }
- }
-
- public int getInt(int pos) {
- if (byteOrder == ByteOrder.BigEndian) {
- return
- (data[pos + 0] & 0xff) << 24 |
- (data[pos + 1] & 0xff) << 16 |
- (data[pos + 2] & 0xff) << 8 |
- (data[pos + 3] & 0xff) << 0;
- } else {
- assert byteOrder == ByteOrder.LittleEndian;
- return
- (data[pos + 3] & 0xff) << 24 |
- (data[pos + 2] & 0xff) << 16 |
- (data[pos + 1] & 0xff) << 8 |
- (data[pos + 0] & 0xff) << 0;
- }
- }
-
- public byte[] copyData(int start, int end) {
- return Arrays.copyOfRange(data, start, end);
- }
-
- /**
- * Copies the data from this buffer into a given array.
- *
- * @param dst the destination array
- * @param off starting position in {@code dst}
- * @param len number of bytes to copy
- */
- public void copyInto(byte[] dst, int off, int len) {
- System.arraycopy(data, 0, dst, off, len);
- }
-}
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/asm/Label.java
--- a/graal/GraalCompiler/src/com/sun/c1x/asm/Label.java Fri May 13 14:03:03 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.c1x.asm;
-
-import com.sun.c1x.util.*;
-
-/**
- * This class represents a label within assembly code.
- *
- * @author Marcelo Cintra
- */
-public final class Label {
-
- private int position = -1;
-
- /**
- * References to instructions that jump to this unresolved label.
- * These instructions need to be patched when the label is bound
- * using the {@link #patchInstructions(AbstractAssembler)} method.
- */
- private IntList patchPositions = new IntList(4);
-
- /**
- * Returns the position of this label in the code buffer.
- * @return the position
- */
- public int position() {
- assert position >= 0 : "Unbound label is being referenced";
- return position;
- }
-
- public Label() {
- }
-
- public Label(int position) {
- bind(position);
- }
-
- /**
- * Binds the label to the specified position.
- * @param pos the position
- */
- public void bind(int pos) {
- this.position = pos;
- assert isBound();
- }
-
- public boolean isBound() {
- return position >= 0;
- }
-
- public void addPatchAt(int branchLocation) {
- assert !isBound() : "Label is already bound";
- patchPositions.add(branchLocation);
- }
-
- public void patchInstructions(AbstractAssembler masm) {
- assert isBound() : "Label should be bound";
- int target = position;
- for (int i = 0; i < patchPositions.size(); ++i) {
- int pos = patchPositions.get(i);
- masm.patchJumpTarget(pos, target);
- }
- }
-
- @Override
- public String toString() {
- return "label";
- }
-}
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/asm/TargetMethodAssembler.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/GraalCompiler/src/com/sun/c1x/asm/TargetMethodAssembler.java Fri May 13 17:09:20 2011 -0700
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x.asm;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.sun.c1x.*;
+import com.sun.c1x.debug.*;
+import com.sun.c1x.ir.*;
+import com.sun.c1x.lir.*;
+import com.sun.c1x.util.*;
+import com.sun.cri.ci.*;
+import com.sun.cri.ri.*;
+
+public class TargetMethodAssembler {
+ public final AbstractAssembler asm;
+ public final CiTargetMethod targetMethod;
+ public List exceptionInfoList;
+ protected int lastSafepointPos;
+
+ public TargetMethodAssembler(AbstractAssembler asm) {
+ this.asm = asm;
+ this.targetMethod = new CiTargetMethod();
+ }
+
+ public void setFrameSize(int frameSize) {
+ targetMethod.setFrameSize(frameSize);
+ }
+
+ public CiTargetMethod.Mark recordMark(Object id, CiTargetMethod.Mark[] references) {
+ return targetMethod.recordMark(asm.codeBuffer.position(), id, references);
+ }
+
+ public void blockComment(String s) {
+ targetMethod.addAnnotation(new CiTargetMethod.CodeComment(asm.codeBuffer.position(), s));
+ }
+
+ public CiTargetMethod finishTargetMethod(Object name, RiRuntime runtime, int registerRestoreEpilogueOffset, boolean isStub) {
+ // Install code, data and frame size
+ targetMethod.setTargetCode(asm.codeBuffer.close(false), asm.codeBuffer.position());
+ targetMethod.setRegisterRestoreEpilogueOffset(registerRestoreEpilogueOffset);
+
+ // Record exception handlers if they exist
+ if (exceptionInfoList != null) {
+ for (ExceptionInfo ei : exceptionInfoList) {
+ int codeOffset = ei.codeOffset;
+ for (ExceptionHandler handler : ei.exceptionHandlers) {
+ int entryOffset = handler.entryCodeOffset();
+ RiType caughtType = handler.handler.catchType();
+ targetMethod.recordExceptionHandler(codeOffset, ei.bci, 0, entryOffset, handler.handlerBCI(), caughtType);
+ }
+ }
+ }
+
+ if (C1XOptions.PrintMetrics) {
+ C1XMetrics.TargetMethods++;
+ C1XMetrics.CodeBytesEmitted += targetMethod.targetCodeSize();
+ C1XMetrics.SafepointsEmitted += targetMethod.safepoints.size();
+ C1XMetrics.DirectCallSitesEmitted += targetMethod.directCalls.size();
+ C1XMetrics.IndirectCallSitesEmitted += targetMethod.indirectCalls.size();
+ C1XMetrics.DataPatches += targetMethod.dataReferences.size();
+ C1XMetrics.ExceptionHandlersEmitted += targetMethod.exceptionHandlers.size();
+ }
+
+ if (C1XOptions.PrintAssembly && !TTY.isSuppressed() && !isStub) {
+ Util.printSection("Target Method", Util.SECTION_CHARACTER);
+ TTY.println("Name: " + name);
+ TTY.println("Frame size: " + targetMethod.frameSize());
+ TTY.println("Register size: " + asm.target.arch.registerReferenceMapBitCount);
+
+ if (C1XOptions.PrintCodeBytes) {
+ Util.printSection("Code", Util.SUB_SECTION_CHARACTER);
+ TTY.println("Code: %d bytes", targetMethod.targetCodeSize());
+ Util.printBytes(0L, targetMethod.targetCode(), 0, targetMethod.targetCodeSize(), C1XOptions.PrintAssemblyBytesPerLine);
+ }
+
+ Util.printSection("Disassembly", Util.SUB_SECTION_CHARACTER);
+ String disassembly = runtime.disassemble(targetMethod);
+ TTY.println(disassembly);
+ boolean noDis = disassembly == null || disassembly.length() == 0;
+
+ Util.printSection("Safepoints", Util.SUB_SECTION_CHARACTER);
+ for (CiTargetMethod.Safepoint x : targetMethod.safepoints) {
+ TTY.println(x.toString());
+ if (noDis && x.debugInfo != null) {
+ TTY.println(CiUtil.indent(x.debugInfo.toString(), " "));
+ }
+ }
+
+ Util.printSection("Direct Call Sites", Util.SUB_SECTION_CHARACTER);
+ for (CiTargetMethod.Call x : targetMethod.directCalls) {
+ TTY.println(x.toString());
+ if (noDis && x.debugInfo != null) {
+ TTY.println(CiUtil.indent(x.debugInfo.toString(), " "));
+ }
+ }
+
+ Util.printSection("Indirect Call Sites", Util.SUB_SECTION_CHARACTER);
+ for (CiTargetMethod.Call x : targetMethod.indirectCalls) {
+ TTY.println(x.toString());
+ if (noDis && x.debugInfo != null) {
+ TTY.println(CiUtil.indent(x.debugInfo.toString(), " "));
+ }
+ }
+
+ Util.printSection("Data Patches", Util.SUB_SECTION_CHARACTER);
+ for (CiTargetMethod.DataPatch x : targetMethod.dataReferences) {
+ TTY.println(x.toString());
+ }
+
+ Util.printSection("Marks", Util.SUB_SECTION_CHARACTER);
+ for (CiTargetMethod.Mark x : targetMethod.marks) {
+ TTY.println(x.toString());
+ }
+
+ Util.printSection("Exception Handlers", Util.SUB_SECTION_CHARACTER);
+ for (CiTargetMethod.ExceptionHandler x : targetMethod.exceptionHandlers) {
+ TTY.println(x.toString());
+ }
+ }
+
+ return targetMethod;
+ }
+
+ public void recordExceptionHandlers(int pcOffset, LIRDebugInfo info) {
+ if (info != null) {
+ if (info.exceptionHandlers != null) {
+ if (exceptionInfoList == null) {
+ exceptionInfoList = new ArrayList(4);
+ }
+ exceptionInfoList.add(new ExceptionInfo(pcOffset, info.exceptionHandlers, info.state.bci));
+ }
+ }
+ }
+
+ public void recordImplicitException(int pcOffset, LIRDebugInfo info) {
+ // record an implicit exception point
+ if (info != null) {
+ assert lastSafepointPos < pcOffset;
+ lastSafepointPos = pcOffset;
+ targetMethod.recordSafepoint(pcOffset, info.debugInfo());
+ recordExceptionHandlers(pcOffset, info);
+ }
+ }
+
+ public void recordDirectCall(int posBefore, int posAfter, Object target, LIRDebugInfo info) {
+ CiDebugInfo debugInfo = info != null ? info.debugInfo() : null;
+ assert lastSafepointPos < posAfter;
+ lastSafepointPos = posAfter;
+ targetMethod.recordCall(posBefore, target, debugInfo, true);
+ }
+
+ public void recordIndirectCall(int posBefore, int posAfter, Object target, LIRDebugInfo info) {
+ CiDebugInfo debugInfo = info != null ? info.debugInfo() : null;
+ assert lastSafepointPos < posAfter;
+ lastSafepointPos = posAfter;
+ targetMethod.recordCall(posBefore, target, debugInfo, false);
+ }
+
+ public void recordSafepoint(int pos, LIRDebugInfo info) {
+ // safepoints always need debug info
+ CiDebugInfo debugInfo = info.debugInfo();
+ assert lastSafepointPos < pos;
+ lastSafepointPos = pos;
+ targetMethod.recordSafepoint(pos, debugInfo);
+ }
+
+ public CiAddress recordDataReferenceInCode(CiConstant data) {
+ assert data != null;
+
+ int pos = asm.codeBuffer.position();
+
+ if (C1XOptions.TraceRelocation) {
+ TTY.print("Data reference in code: pos = %d, data = %s", pos, data.toString());
+ }
+
+ targetMethod.recordDataReference(pos, data);
+ return CiAddress.Placeholder;
+ }
+
+ public int lastSafepointPos() {
+ return lastSafepointPos;
+ }
+}
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java
--- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Fri May 13 17:09:20 2011 -0700
@@ -29,10 +29,10 @@
import java.util.*;
+import com.oracle.max.asm.*;
import com.sun.c1x.*;
import com.sun.c1x.alloc.*;
import com.sun.c1x.alloc.OperandPool.VariableFlag;
-import com.sun.c1x.asm.*;
import com.sun.c1x.debug.*;
import com.sun.c1x.globalstub.*;
import com.sun.c1x.graph.*;
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java Fri May 13 17:09:20 2011 -0700
@@ -25,8 +25,8 @@
import java.util.*;
import com.oracle.graal.graph.*;
+import com.oracle.max.asm.*;
import com.sun.c1x.*;
-import com.sun.c1x.asm.*;
import com.sun.c1x.debug.*;
import com.sun.c1x.lir.*;
import com.sun.c1x.util.*;
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/lir/FrameMap.java
--- a/graal/GraalCompiler/src/com/sun/c1x/lir/FrameMap.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/lir/FrameMap.java Fri May 13 17:09:20 2011 -0700
@@ -33,6 +33,7 @@
import com.sun.cri.ci.*;
import com.sun.cri.ci.CiCallingConvention.Type;
import com.sun.cri.ri.*;
+import com.sun.cri.util.*;
/**
* This class is used to build the stack frame layout for a compiled method.
@@ -133,7 +134,7 @@
incomingArguments = new CiCallingConvention(new CiValue[0], 0);
} else {
CiKind receiver = !isStatic(method.accessFlags()) ? method.holder().kind() : null;
- incomingArguments = getCallingConvention(Util.signatureToKinds(method.signature(), receiver), JavaCallee);
+ incomingArguments = getCallingConvention(CRIUtil.signatureToKinds(method.signature(), receiver), JavaCallee);
}
}
@@ -215,8 +216,8 @@
public CiAddress toStackAddress(CiStackSlot slot) {
int size = compilation.target.sizeInBytes(slot.kind);
if (slot.inCallerFrame()) {
- int offset = slot.index() * compilation.target.spillSlotSize;
- return new CiAddress(slot.kind, CiRegister.CallerFrame.asValue(), offset);
+ int offset = slot.index() * compilation.target.spillSlotSize + frameSize() + 8;
+ return new CiAddress(slot.kind, CiRegister.Frame.asValue(), offset);
} else {
int offset = offsetForOutgoingOrSpillSlot(slot.index(), size);
return new CiAddress(slot.kind, CiRegister.Frame.asValue(), offset);
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/lir/LIRAssembler.java
--- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRAssembler.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRAssembler.java Fri May 13 17:09:20 2011 -0700
@@ -24,6 +24,7 @@
import java.util.*;
+import com.oracle.max.asm.*;
import com.sun.c1x.*;
import com.sun.c1x.asm.*;
import com.sun.c1x.debug.*;
@@ -38,14 +39,11 @@
/**
* The {@code LIRAssembler} class definition.
- *
- * @author Marcelo Cintra
- * @author Thomas Wuerthinger
- * @author Ben L. Titzer
*/
public abstract class LIRAssembler {
public final C1XCompilation compilation;
+ public final TargetMethodAssembler tasm;
public final AbstractAssembler asm;
public final FrameMap frameMap;
public int registerRestoreEpilogueOffset = -1;
@@ -69,7 +67,8 @@
public LIRAssembler(C1XCompilation compilation) {
this.compilation = compilation;
- this.asm = compilation.masm();
+ this.tasm = compilation.assembler();
+ this.asm = tasm.asm;
this.frameMap = compilation.frameMap();
this.branchTargetBlocks = new ArrayList();
this.xirSlowPath = new ArrayList();
@@ -98,10 +97,10 @@
public abstract void emitTraps();
public void emitExceptionEntries() {
- if (asm.exceptionInfoList == null) {
+ if (tasm.exceptionInfoList == null) {
return;
}
- for (ExceptionInfo ilist : asm.exceptionInfoList) {
+ for (ExceptionInfo ilist : tasm.exceptionInfoList) {
List handlers = ilist.exceptionHandlers;
for (ExceptionHandler handler : handlers) {
@@ -113,7 +112,7 @@
if (handler.entryCode() != null && handler.entryCode().instructionsList().size() > 1) {
handler.setEntryCodeOffset(codePos());
if (C1XOptions.CommentedAssembly) {
- asm.blockComment("Exception adapter block");
+ tasm.blockComment("Exception adapter block");
}
emitLirList(handler.entryCode());
} else {
@@ -157,7 +156,7 @@
assert block.lir() != null : "must have LIR";
if (C1XOptions.CommentedAssembly) {
String st = String.format(" block B%d [%d, %d]", block.blockID, block.bci(), block.end().bci());
- asm.blockComment(st);
+ tasm.blockComment(st);
}
emitLirList(block.lir());
@@ -170,7 +169,7 @@
if (C1XOptions.CommentedAssembly) {
// Only print out branches
if (op.code == LIROpcode.Branch) {
- asm.blockComment(op.toStringWithIdPrefix());
+ tasm.blockComment(op.toStringWithIdPrefix());
}
}
if (C1XOptions.PrintLIRWithAssembly && !TTY.isSuppressed()) {
@@ -220,15 +219,15 @@
emitCallAlignment(op.code);
// fall through
case ConstDirectCall:
- if (op.marks != null) {
- op.marks.put(XirMark.CALLSITE, asm.recordMark(null, new Mark[0]));
+ if (op.marks != null) {
+ op.marks.put(XirMark.CALLSITE, tasm.recordMark(null, new Mark[0]));
}
emitDirectCall(op.target, op.info);
break;
case IndirectCall:
emitCallAlignment(op.code);
if (op.marks != null) {
- op.marks.put(XirMark.CALLSITE, asm.recordMark(null, new Mark[0]));
+ op.marks.put(XirMark.CALLSITE, tasm.recordMark(null, new Mark[0]));
}
emitIndirectCall(op.target, op.info, op.targetAddress());
break;
@@ -274,12 +273,7 @@
emitLea(op.operand(), op.result());
break;
case NullCheck:
- assert op.operand().isRegister();
- if (C1XOptions.NullCheckUniquePc) {
- asm.nop();
- }
- asm.recordImplicitException(codePos(), op.info);
- asm.nullCheck(op.operand().asRegister());
+ emitNullCheck(op.operand(), op.info);
break;
case Lsb:
emitSignificantBitOp(false, op.operand(), op.result());
@@ -287,7 +281,7 @@
case Msb:
emitSignificantBitOp(true, op.operand(), op.result());
break;
- default:
+ default:
throw Util.shouldNotReachHere();
}
}
@@ -448,6 +442,8 @@
protected abstract void emitLea(CiValue src, CiValue dst);
+ protected abstract void emitNullCheck(CiValue src, LIRDebugInfo info);
+
protected abstract void emitNegate(LIRNegate negate);
protected abstract void emitHere(CiValue dst, LIRDebugInfo info, boolean infoOnly);
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java
--- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java Fri May 13 17:09:20 2011 -0700
@@ -22,8 +22,8 @@
*/
package com.sun.c1x.lir;
+import com.oracle.max.asm.*;
import com.sun.c1x.alloc.*;
-import com.sun.c1x.asm.*;
import com.sun.cri.ci.*;
/**
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/lir/LIRBranch.java
--- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBranch.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBranch.java Fri May 13 17:09:20 2011 -0700
@@ -22,7 +22,7 @@
*/
package com.sun.c1x.lir;
-import com.sun.c1x.asm.*;
+import com.oracle.max.asm.*;
import com.sun.c1x.ir.*;
import com.sun.cri.ci.*;
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/lir/LIRLabel.java
--- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRLabel.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRLabel.java Fri May 13 17:09:20 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
*/
package com.sun.c1x.lir;
-import com.sun.c1x.asm.*;
+import com.oracle.max.asm.*;
import com.sun.cri.ci.*;
/**
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/lir/LIRList.java
--- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRList.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRList.java Fri May 13 17:09:20 2011 -0700
@@ -24,9 +24,9 @@
import java.util.*;
+import com.oracle.max.asm.*;
import com.sun.c1x.*;
import com.sun.c1x.alloc.*;
-import com.sun.c1x.asm.*;
import com.sun.c1x.debug.*;
import com.sun.c1x.gen.*;
import com.sun.c1x.globalstub.*;
@@ -41,10 +41,6 @@
/**
* This class represents a list of LIR instructions and contains factory methods for creating and appending LIR
* instructions to this list.
- *
- * @author Marcelo Cintra
- * @author Thomas Wuerthinger
- * @author Ben L. Titzer
*/
public final class LIRList {
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/target/Backend.java
--- a/graal/GraalCompiler/src/com/sun/c1x/target/Backend.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/target/Backend.java Fri May 13 17:09:20 2011 -0700
@@ -24,8 +24,8 @@
import java.lang.reflect.*;
+import com.oracle.max.asm.*;
import com.sun.c1x.*;
-import com.sun.c1x.asm.*;
import com.sun.c1x.gen.*;
import com.sun.c1x.globalstub.*;
import com.sun.c1x.lir.*;
@@ -46,13 +46,13 @@
}
public static Backend create(CiArchitecture arch, C1XCompiler compiler) {
- String className = arch.getClass().getName() + "Backend";
+ String className = arch.getClass().getName().replace("com.oracle.max.asm", "com.sun.c1x") + "Backend";
try {
Class> c = Class.forName(className);
Constructor> cons = c.getDeclaredConstructor(C1XCompiler.class);
return (Backend) cons.newInstance(compiler);
} catch (Exception e) {
- throw new Error("Could instantiate " + className, e);
+ throw new Error("Could not instantiate " + className, e);
}
}
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64.java
--- a/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64.java Fri May 13 14:03:03 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.c1x.target.amd64;
-
-import static com.sun.cri.bytecode.Bytecodes.MemoryBarriers.*;
-import static com.sun.cri.ci.CiKind.*;
-import static com.sun.cri.ci.CiRegister.RegisterFlag.*;
-
-import com.sun.cri.ci.*;
-import com.sun.cri.ci.CiRegister.RegisterFlag;
-
-/**
- * Represents the AMD64 architecture.
- *
- * @author Thomas Wuerthinger
- */
-public class AMD64 extends CiArchitecture {
-
- // General purpose CPU registers
- public static final CiRegister rax = new CiRegister(0, 0, 8, "rax", CPU, RegisterFlag.Byte);
- public static final CiRegister rcx = new CiRegister(1, 1, 8, "rcx", CPU, RegisterFlag.Byte);
- public static final CiRegister rdx = new CiRegister(2, 2, 8, "rdx", CPU, RegisterFlag.Byte);
- public static final CiRegister rbx = new CiRegister(3, 3, 8, "rbx", CPU, RegisterFlag.Byte);
- public static final CiRegister rsp = new CiRegister(4, 4, 8, "rsp", CPU, RegisterFlag.Byte);
- public static final CiRegister rbp = new CiRegister(5, 5, 8, "rbp", CPU, RegisterFlag.Byte);
- public static final CiRegister rsi = new CiRegister(6, 6, 8, "rsi", CPU, RegisterFlag.Byte);
- public static final CiRegister rdi = new CiRegister(7, 7, 8, "rdi", CPU, RegisterFlag.Byte);
-
- public static final CiRegister r8 = new CiRegister(8, 8, 8, "r8", CPU, RegisterFlag.Byte);
- public static final CiRegister r9 = new CiRegister(9, 9, 8, "r9", CPU, RegisterFlag.Byte);
- public static final CiRegister r10 = new CiRegister(10, 10, 8, "r10", CPU, RegisterFlag.Byte);
- public static final CiRegister r11 = new CiRegister(11, 11, 8, "r11", CPU, RegisterFlag.Byte);
- public static final CiRegister r12 = new CiRegister(12, 12, 8, "r12", CPU, RegisterFlag.Byte);
- public static final CiRegister r13 = new CiRegister(13, 13, 8, "r13", CPU, RegisterFlag.Byte);
- public static final CiRegister r14 = new CiRegister(14, 14, 8, "r14", CPU, RegisterFlag.Byte);
- public static final CiRegister r15 = new CiRegister(15, 15, 8, "r15", CPU, RegisterFlag.Byte);
-
- public static final CiRegister[] cpuRegisters = {
- rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
- r8, r9, r10, r11, r12, r13, r14, r15
- };
-
- // XMM registers
- public static final CiRegister xmm0 = new CiRegister(16, 0, 8, "xmm0", FPU);
- public static final CiRegister xmm1 = new CiRegister(17, 1, 8, "xmm1", FPU);
- public static final CiRegister xmm2 = new CiRegister(18, 2, 8, "xmm2", FPU);
- public static final CiRegister xmm3 = new CiRegister(19, 3, 8, "xmm3", FPU);
- public static final CiRegister xmm4 = new CiRegister(20, 4, 8, "xmm4", FPU);
- public static final CiRegister xmm5 = new CiRegister(21, 5, 8, "xmm5", FPU);
- public static final CiRegister xmm6 = new CiRegister(22, 6, 8, "xmm6", FPU);
- public static final CiRegister xmm7 = new CiRegister(23, 7, 8, "xmm7", FPU);
-
- public static final CiRegister xmm8 = new CiRegister(24, 8, 8, "xmm8", FPU);
- public static final CiRegister xmm9 = new CiRegister(25, 9, 8, "xmm9", FPU);
- public static final CiRegister xmm10 = new CiRegister(26, 10, 8, "xmm10", FPU);
- public static final CiRegister xmm11 = new CiRegister(27, 11, 8, "xmm11", FPU);
- public static final CiRegister xmm12 = new CiRegister(28, 12, 8, "xmm12", FPU);
- public static final CiRegister xmm13 = new CiRegister(29, 13, 8, "xmm13", FPU);
- public static final CiRegister xmm14 = new CiRegister(30, 14, 8, "xmm14", FPU);
- public static final CiRegister xmm15 = new CiRegister(31, 15, 8, "xmm15", FPU);
-
- public static final CiRegister[] xmmRegisters = {
- xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
- xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
- };
-
- public static final CiRegister[] allRegisters = {
- rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
- r8, r9, r10, r11, r12, r13, r14, r15,
- xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
- xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
- };
-
- public static final CiRegisterValue RSP = rsp.asValue(Word);
-
- public AMD64() {
- super("AMD64",
- 8,
- ByteOrder.LittleEndian,
- allRegisters,
- LOAD_STORE | STORE_STORE,
- 1,
- r15.encoding + 1,
- 8);
- }
-
- @Override
- public boolean isX86() {
- return true;
- }
-
- @Override
- public boolean twoOperandMode() {
- return true;
- }
-
-}
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64Assembler.java
--- a/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64Assembler.java Fri May 13 14:03:03 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2878 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.c1x.target.amd64;
-
-import static com.sun.c1x.target.amd64.AMD64.*;
-import static com.sun.cri.bytecode.Bytecodes.MemoryBarriers.*;
-import static com.sun.cri.ci.CiKind.*;
-
-import com.sun.c1x.*;
-import com.sun.c1x.asm.*;
-import com.sun.c1x.lir.*;
-import com.sun.c1x.util.*;
-import com.sun.cri.ci.*;
-import com.sun.cri.ri.*;
-
-/**
- * This class implements an assembler that can encode most X86 instructions.
- *
- * @author Thomas Wuerthinger
- */
-public class AMD64Assembler extends AbstractAssembler {
-
- private static final int MinEncodingNeedsRex = 8;
-
- /**
- * The x86 condition codes used for conditional jumps/moves.
- */
- public enum ConditionFlag {
- zero(0x4),
- notZero(0x5),
- equal(0x4),
- notEqual(0x5),
- less(0xc),
- lessEqual(0xe),
- greater(0xf),
- greaterEqual(0xd),
- below(0x2),
- belowEqual(0x6),
- above(0x7),
- aboveEqual(0x3),
- overflow(0x0),
- noOverflow(0x1),
- carrySet(0x2),
- carryClear(0x3),
- negative(0x8),
- positive(0x9),
- parity(0xa),
- noParity(0xb);
-
- public final int value;
-
- private ConditionFlag(int value) {
- this.value = value;
- }
-
- public static final ConditionFlag[] values = values();
- }
-
- /**
- * Constants for X86 prefix bytes.
- */
- private class Prefix {
- private static final int REX = 0x40;
- private static final int REXB = 0x41;
- private static final int REXX = 0x42;
- private static final int REXXB = 0x43;
- private static final int REXR = 0x44;
- private static final int REXRB = 0x45;
- private static final int REXRX = 0x46;
- private static final int REXRXB = 0x47;
- private static final int REXW = 0x48;
- private static final int REXWB = 0x49;
- private static final int REXWX = 0x4A;
- private static final int REXWXB = 0x4B;
- private static final int REXWR = 0x4C;
- private static final int REXWRB = 0x4D;
- private static final int REXWRX = 0x4E;
- private static final int REXWRXB = 0x4F;
- }
-
- /**
- * The register to which {@link CiRegister#Frame} and {@link CiRegister#CallerFrame} are bound.
- */
- public final CiRegister frameRegister;
-
- /**
- * Constructs an assembler for the AMD64 architecture.
- *
- * @param registerConfig the register configuration used to bind {@link CiRegister#Frame} and
- * {@link CiRegister#CallerFrame} to physical registers. This value can be null if this assembler
- * instance will not be used to assemble instructions using these logical registers.
- */
- public AMD64Assembler(CiTarget target, RiRegisterConfig registerConfig) {
- super(target);
- this.frameRegister = registerConfig == null ? null : registerConfig.getFrameRegister();
- }
-
- private static int encode(CiRegister r) {
- assert r.encoding < 16 && r.encoding >= 0 : "encoding out of range: " + r.encoding;
- return r.encoding & 0x7;
- }
-
- private void emitArithB(int op1, int op2, CiRegister dst, int imm8) {
- assert dst.isByte() : "must have byte register";
- assert Util.isUByte(op1) && Util.isUByte(op2) : "wrong opcode";
- assert Util.isUByte(imm8) : "not a byte";
- assert (op1 & 0x01) == 0 : "should be 8bit operation";
- emitByte(op1);
- emitByte(op2 | encode(dst));
- emitByte(imm8);
- }
-
- private void emitArith(int op1, int op2, CiRegister dst, int imm32) {
- assert Util.isUByte(op1) && Util.isUByte(op2) : "wrong opcode";
- assert (op1 & 0x01) == 1 : "should be 32bit operation";
- assert (op1 & 0x02) == 0 : "sign-extension bit should not be set";
- if (Util.isByte(imm32)) {
- emitByte(op1 | 0x02); // set sign bit
- emitByte(op2 | encode(dst));
- emitByte(imm32 & 0xFF);
- } else {
- emitByte(op1);
- emitByte(op2 | encode(dst));
- emitInt(imm32);
- }
- }
-
- // immediate-to-memory forms
- private void emitArithOperand(int op1, CiRegister rm, CiAddress adr, int imm32) {
- assert (op1 & 0x01) == 1 : "should be 32bit operation";
- assert (op1 & 0x02) == 0 : "sign-extension bit should not be set";
- if (Util.isByte(imm32)) {
- emitByte(op1 | 0x02); // set sign bit
- emitOperandHelper(rm, adr);
- emitByte(imm32 & 0xFF);
- } else {
- emitByte(op1);
- emitOperandHelper(rm, adr);
- emitInt(imm32);
- }
- }
-
- private void emitArith(int op1, int op2, CiRegister dst, CiRegister src) {
- assert Util.isUByte(op1) && Util.isUByte(op2) : "wrong opcode";
- emitByte(op1);
- emitByte(op2 | encode(dst) << 3 | encode(src));
- }
-
- private void emitOperandHelper(CiRegister reg, CiAddress addr) {
- CiRegister base = addr.base();
-
- CiRegister index = addr.index();
- CiAddress.Scale scale = addr.scale;
- int disp = addr.displacement;
-
- if (base == CiRegister.Frame) {
- assert frameRegister != null : "cannot use register " + CiRegister.Frame + " in assembler with null register configuration";
- base = frameRegister;
- } else if (base == CiRegister.CallerFrame) {
- assert frameRegister != null : "cannot use register " + CiRegister.Frame + " in assembler with null register configuration";
- base = frameRegister;
- disp += targetMethod.frameSize() + 8;
- }
-
- // Encode the registers as needed in the fields they are used in
-
- assert reg != CiRegister.None;
-
- int regenc = encode(reg) << 3;
- int indexenc = index.isValid() ? encode(index) << 3 : 0;
- int baseenc = base.isValid() ? encode(base) : 0;
-
- if (base.isValid()) {
- if (index.isValid()) {
- // [base + indexscale + disp]
- if (disp == 0 && base != rbp && (base != r13)) {
- // [base + indexscale]
- // [00 reg 100][ss index base]
- assert index != rsp : "illegal addressing mode";
- emitByte(0x04 | regenc);
- emitByte(scale.log2 << 6 | indexenc | baseenc);
- } else if (Util.isByte(disp)) {
- // [base + indexscale + imm8]
- // [01 reg 100][ss index base] imm8
- assert index != rsp : "illegal addressing mode";
- emitByte(0x44 | regenc);
- emitByte(scale.log2 << 6 | indexenc | baseenc);
- emitByte(disp & 0xFF);
- } else {
- // [base + indexscale + disp32]
- // [10 reg 100][ss index base] disp32
- assert index != rsp : "illegal addressing mode";
- emitByte(0x84 | regenc);
- emitByte(scale.log2 << 6 | indexenc | baseenc);
- emitInt(disp);
- }
- } else if (base == rsp || (base == r12)) {
- // [rsp + disp]
- if (disp == 0) {
- // [rsp]
- // [00 reg 100][00 100 100]
- emitByte(0x04 | regenc);
- emitByte(0x24);
- } else if (Util.isByte(disp)) {
- // [rsp + imm8]
- // [01 reg 100][00 100 100] disp8
- emitByte(0x44 | regenc);
- emitByte(0x24);
- emitByte(disp & 0xFF);
- } else {
- // [rsp + imm32]
- // [10 reg 100][00 100 100] disp32
- emitByte(0x84 | regenc);
- emitByte(0x24);
- emitInt(disp);
- }
- } else {
- // [base + disp]
- assert base != rsp && (base != r12) : "illegal addressing mode";
- if (disp == 0 && base != rbp && (base != r13)) {
- // [base]
- // [00 reg base]
- emitByte(0x00 | regenc | baseenc);
- } else if (Util.isByte(disp)) {
- // [base + disp8]
- // [01 reg base] disp8
- emitByte(0x40 | regenc | baseenc);
- emitByte(disp & 0xFF);
- } else {
- // [base + disp32]
- // [10 reg base] disp32
- emitByte(0x80 | regenc | baseenc);
- emitInt(disp);
- }
- }
- } else {
- if (index.isValid()) {
- // [indexscale + disp]
- // [00 reg 100][ss index 101] disp32
- assert index != rsp : "illegal addressing mode";
- emitByte(0x04 | regenc);
- emitByte(scale.log2 << 6 | indexenc | 0x05);
- emitInt(disp);
- } else if (base == CiRegister.InstructionRelative) {
- // Adjust disp which is currently relative to the start of the instruction
- int instrStart = codeBuffer.mark();
- assert instrStart >= 0;
- int instrSize = (codeBuffer.position() - instrStart) + 5;
- disp = disp - instrSize;
- // [00 000 101] disp32
- emitByte(0x05 | regenc);
- emitInt(disp);
- } else if (addr == CiAddress.Placeholder) {
- // [00 000 101] disp32
- emitByte(0x05 | regenc);
- emitInt(0);
- } else {
- // [disp] ABSOLUTE
- // [00 reg 100][00 100 101] disp32
- emitByte(0x04 | regenc);
- emitByte(0x25);
- emitInt(disp);
- }
- }
- }
-
- public final void addl(CiAddress dst, int imm32) {
- prefix(dst);
- emitArithOperand(0x81, rax, dst, imm32);
- }
-
- public final void addl(CiAddress dst, CiRegister src) {
- prefix(dst, src);
- emitByte(0x01);
- emitOperandHelper(src, dst);
- }
-
- public final void addl(CiRegister dst, int imm32) {
- prefix(dst);
- emitArith(0x81, 0xC0, dst, imm32);
- }
-
- public final void addl(CiRegister dst, CiAddress src) {
- prefix(src, dst);
- emitByte(0x03);
- emitOperandHelper(dst, src);
- }
-
- public final void addl(CiRegister dst, CiRegister src) {
- prefixAndEncode(dst.encoding, src.encoding);
- emitArith(0x03, 0xC0, dst, src);
- }
-
- private void addrNop4() {
- // 4 bytes: NOP DWORD PTR [EAX+0]
- emitByte(0x0F);
- emitByte(0x1F);
- emitByte(0x40); // emitRm(cbuf, 0x1, EAXEnc, EAXEnc);
- emitByte(0); // 8-bits offset (1 byte)
- }
-
- private void addrNop5() {
- // 5 bytes: NOP DWORD PTR [EAX+EAX*0+0] 8-bits offset
- emitByte(0x0F);
- emitByte(0x1F);
- emitByte(0x44); // emitRm(cbuf, 0x1, EAXEnc, 0x4);
- emitByte(0x00); // emitRm(cbuf, 0x0, EAXEnc, EAXEnc);
- emitByte(0); // 8-bits offset (1 byte)
- }
-
- private void addrNop7() {
- // 7 bytes: NOP DWORD PTR [EAX+0] 32-bits offset
- emitByte(0x0F);
- emitByte(0x1F);
- emitByte(0x80); // emitRm(cbuf, 0x2, EAXEnc, EAXEnc);
- emitInt(0); // 32-bits offset (4 bytes)
- }
-
- private void addrNop8() {
- // 8 bytes: NOP DWORD PTR [EAX+EAX*0+0] 32-bits offset
- emitByte(0x0F);
- emitByte(0x1F);
- emitByte(0x84); // emitRm(cbuf, 0x2, EAXEnc, 0x4);
- emitByte(0x00); // emitRm(cbuf, 0x0, EAXEnc, EAXEnc);
- emitInt(0); // 32-bits offset (4 bytes)
- }
-
- public final void addsd(CiRegister dst, CiRegister src) {
- assert dst.isFpu() && src.isFpu();
- emitByte(0xF2);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x58);
- emitByte(0xC0 | encode);
- }
-
- public final void addsd(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
- emitByte(0xF2);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x58);
- emitOperandHelper(dst, src);
- }
-
- public final void addss(CiRegister dst, CiRegister src) {
- assert dst.isFpu() && src.isFpu();
- emitByte(0xF3);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x58);
- emitByte(0xC0 | encode);
- }
-
- public final void addss(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
- emitByte(0xF3);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x58);
- emitOperandHelper(dst, src);
- }
-
- public final void andl(CiRegister dst, int imm32) {
- prefix(dst);
- emitArith(0x81, 0xE0, dst, imm32);
- }
-
- public final void andl(CiRegister dst, CiAddress src) {
- prefix(src, dst);
- emitByte(0x23);
- emitOperandHelper(dst, src);
- }
-
- public final void andl(CiRegister dst, CiRegister src) {
- prefixAndEncode(dst.encoding, src.encoding);
- emitArith(0x23, 0xC0, dst, src);
- }
-
- public final void andpd(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
- emitByte(0x66);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x54);
- emitOperandHelper(dst, src);
- }
-
- public final void bsfq(CiRegister dst, CiRegister src) {
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0xBC);
- emitByte(0xC0 | encode);
- }
-
- public final void bsfq(CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0xBC);
- emitOperandHelper(dst, src);
- }
-
- public final void bsrq(CiRegister dst, CiRegister src) {
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0xBD);
- emitByte(0xC0 | encode);
- }
-
-
- public final void bsrq(CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0xBD);
- emitOperandHelper(dst, src);
- }
-
- public final void bswapl(CiRegister reg) { // bswap
- int encode = prefixAndEncode(reg.encoding);
- emitByte(0x0F);
- emitByte(0xC8 | encode);
- }
-
- public final void btli(CiAddress src, int imm8) {
- prefixq(src);
- emitByte(0x0F);
- emitByte(0xBA);
- emitOperandHelper(rsp, src);
- emitByte(imm8);
- }
-
- public final void nativeCall(CiRegister dst, String symbol, LIRDebugInfo info) {
- int before = codeBuffer.position();
- int encode = prefixAndEncode(dst.encoding);
- emitByte(0xFF);
- emitByte(0xD0 | encode);
- int after = codeBuffer.position();
- recordIndirectCall(before, after, symbol, info);
- recordExceptionHandlers(after, info);
- }
-
- public final int directCall(Object target, LIRDebugInfo info) {
- int before = codeBuffer.position();
- emitByte(0xE8);
- emitInt(0);
- int after = codeBuffer.position();
- recordDirectCall(before, after, target, info);
- recordExceptionHandlers(after, info);
- return before;
- }
-
- public final int directJmp(Object target) {
- int before = codeBuffer.position();
- emitByte(0xE9);
- emitInt(0);
- int after = codeBuffer.position();
- recordDirectCall(before, after, target, null);
- return before;
- }
-
- public final int indirectCall(CiRegister dst, Object target, LIRDebugInfo info) {
- int before = codeBuffer.position();
- int encode = prefixAndEncode(dst.encoding);
-
- emitByte(0xFF);
- emitByte(0xD0 | encode);
- int after = codeBuffer.position();
- recordIndirectCall(before, after, target, info);
- recordExceptionHandlers(after, info);
- return before;
- }
-
- public final void cdql() {
- emitByte(0x99);
- }
-
- public final void cmovl(ConditionFlag cc, CiRegister dst, CiRegister src) {
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x40 | cc.value);
- emitByte(0xC0 | encode);
- }
-
- public final void cmovl(ConditionFlag cc, CiRegister dst, CiAddress src) {
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x40 | cc.value);
- emitOperandHelper(dst, src);
- }
-
- public final void cmpb(CiAddress dst, int imm8) {
- prefix(dst);
- emitByte(0x80);
- emitOperandHelper(rdi, dst);
- emitByte(imm8);
- }
-
- public final void cmpl(CiAddress dst, int imm32) {
- prefix(dst);
- emitByte(0x81);
- emitOperandHelper(rdi, dst);
- emitInt(imm32);
- }
-
- public final void cmpl(CiRegister dst, int imm32) {
- prefix(dst);
- emitArith(0x81, 0xF8, dst, imm32);
- }
-
- public final void cmpl(CiRegister dst, CiRegister src) {
- prefixAndEncode(dst.encoding, src.encoding);
- emitArith(0x3B, 0xC0, dst, src);
- }
-
- public final void cmpl(CiRegister dst, CiAddress src) {
- prefix(src, dst);
- emitByte(0x3B);
- emitOperandHelper(dst, src);
- }
-
- // The 32-bit cmpxchg compares the value at adr with the contents of X86.rax,
- // and stores reg into adr if so; otherwise, the value at adr is loaded into X86.rax,.
- // The ZF is set if the compared values were equal, and cleared otherwise.
- public final void cmpxchgl(CiRegister reg, CiAddress adr) { // cmpxchg
- if ((C1XOptions.Atomics & 2) != 0) {
- // caveat: no instructionmark, so this isn't relocatable.
- // Emit a synthetic, non-atomic, CAS equivalent.
- // Beware. The synthetic form sets all ICCs, not just ZF.
- // cmpxchg r,[m] is equivalent to X86.rax, = CAS (m, X86.rax, r)
- cmpl(rax, adr);
- movl(rax, adr);
- if (reg != rax) {
- Label l = new Label();
- jcc(ConditionFlag.notEqual, l);
- movl(adr, reg);
- bind(l);
- }
- } else {
-
- prefix(adr, reg);
- emitByte(0x0F);
- emitByte(0xB1);
- emitOperandHelper(reg, adr);
- }
- }
-
- public final void comisd(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
- // NOTE: dbx seems to decode this as comiss even though the
- // 0x66 is there. Strangly ucomisd comes out correct
- emitByte(0x66);
- comiss(dst, src);
- }
-
- public final void comiss(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
-
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x2F);
- emitOperandHelper(dst, src);
- }
-
- public final void cvtdq2pd(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
-
- emitByte(0xF3);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0xE6);
- emitByte(0xC0 | encode);
- }
-
- public final void cvtdq2ps(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x5B);
- emitByte(0xC0 | encode);
- }
-
- public final void cvtsd2ss(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- emitByte(0xF2);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x5A);
- emitByte(0xC0 | encode);
- }
-
- public final void cvtsi2sdl(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- emitByte(0xF2);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x2A);
- emitByte(0xC0 | encode);
- }
-
- public final void cvtsi2ssl(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- emitByte(0xF3);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x2A);
- emitByte(0xC0 | encode);
- }
-
- public final void cvtss2sd(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- emitByte(0xF3);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x5A);
- emitByte(0xC0 | encode);
- }
-
- public final void cvttsd2sil(CiRegister dst, CiRegister src) {
- assert src.isFpu();
- emitByte(0xF2);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x2C);
- emitByte(0xC0 | encode);
- }
-
- public final void cvttss2sil(CiRegister dst, CiRegister src) {
- assert src.isFpu();
- emitByte(0xF3);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x2C);
- emitByte(0xC0 | encode);
- }
-
- public final void decl(CiAddress dst) {
- // Don't use it directly. Use Macrodecrement() instead.
- prefix(dst);
- emitByte(0xFF);
- emitOperandHelper(rcx, dst);
- }
-
- public final void divsd(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
- emitByte(0xF2);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x5E);
- emitOperandHelper(dst, src);
- }
-
- public final void divsd(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- emitByte(0xF2);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x5E);
- emitByte(0xC0 | encode);
- }
-
- public final void divss(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
- emitByte(0xF3);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x5E);
- emitOperandHelper(dst, src);
- }
-
- public final void divss(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- emitByte(0xF3);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x5E);
- emitByte(0xC0 | encode);
- }
-
- public final void hlt() {
- emitByte(0xF4);
- }
-
- public final void idivl(CiRegister src) {
- int encode = prefixAndEncode(src.encoding);
- emitByte(0xF7);
- emitByte(0xF8 | encode);
- }
-
- public final void imull(CiRegister dst, CiRegister src) {
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0xAF);
- emitByte(0xC0 | encode);
- }
-
- public final void imull(CiRegister dst, CiRegister src, int value) {
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- if (Util.isByte(value)) {
- emitByte(0x6B);
- emitByte(0xC0 | encode);
- emitByte(value);
- } else {
- emitByte(0x69);
- emitByte(0xC0 | encode);
- emitInt(value);
- }
- }
-
- public final void incl(CiAddress dst) {
- // Don't use it directly. Use Macroincrement() instead.
- prefix(dst);
- emitByte(0xFF);
- emitOperandHelper(rax, dst);
- }
-
- public final void jcc(ConditionFlag cc, int target, boolean forceDisp32) {
- int shortSize = 2;
- int longSize = 6;
- long disp = target - codeBuffer.position();
- if (!forceDisp32 && Util.isByte(disp - shortSize)) {
- // 0111 tttn #8-bit disp
- emitByte(0x70 | cc.value);
- emitByte((int) ((disp - shortSize) & 0xFF));
- } else {
- // 0000 1111 1000 tttn #32-bit disp
- assert Util.isInt(disp - longSize) : "must be 32bit offset (call4)";
- emitByte(0x0F);
- emitByte(0x80 | cc.value);
- emitInt((int) (disp - longSize));
- }
- }
-
- public final void jcc(ConditionFlag cc, Label l) {
- assert (0 <= cc.value) && (cc.value < 16) : "illegal cc";
- if (l.isBound()) {
- jcc(cc, l.position(), false);
- } else {
- // Note: could eliminate cond. jumps to this jump if condition
- // is the same however, seems to be rather unlikely case.
- // Note: use jccb() if label to be bound is very close to get
- // an 8-bit displacement
- l.addPatchAt(codeBuffer.position());
- emitByte(0x0F);
- emitByte(0x80 | cc.value);
- emitInt(0);
- }
-
- }
-
- public final void jccb(ConditionFlag cc, Label l) {
- if (l.isBound()) {
- int shortSize = 2;
- int entry = l.position();
- assert Util.isByte(entry - (codeBuffer.position() + shortSize)) : "Dispacement too large for a short jmp";
- long disp = entry - codeBuffer.position();
- // 0111 tttn #8-bit disp
- emitByte(0x70 | cc.value);
- emitByte((int) ((disp - shortSize) & 0xFF));
- } else {
-
- l.addPatchAt(codeBuffer.position());
- emitByte(0x70 | cc.value);
- emitByte(0);
- }
- }
-
- public final void jmp(CiAddress adr) {
- prefix(adr);
- emitByte(0xFF);
- emitOperandHelper(rsp, adr);
- }
-
- public final void jmp(int target, boolean forceDisp32) {
- int shortSize = 2;
- int longSize = 5;
- long disp = target - codeBuffer.position();
- if (!forceDisp32 && Util.isByte(disp - shortSize)) {
- emitByte(0xEB);
- emitByte((int) ((disp - shortSize) & 0xFF));
- } else {
- emitByte(0xE9);
- emitInt((int) (disp - longSize));
- }
- }
-
- public final void jmp(Label l) {
- if (l.isBound()) {
- jmp(l.position(), false);
- } else {
- // By default, forward jumps are always 32-bit displacements, since
- // we can't yet know where the label will be bound. If you're sure that
- // the forward jump will not run beyond 256 bytes, use jmpb to
- // force an 8-bit displacement.
-
- l.addPatchAt(codeBuffer.position());
- emitByte(0xE9);
- emitInt(0);
- }
- }
-
- public final void jmp(CiRegister entry) {
- int encode = prefixAndEncode(entry.encoding);
- emitByte(0xFF);
- emitByte(0xE0 | encode);
- }
-
- public final void jmpb(Label l) {
- if (l.isBound()) {
- int shortSize = 2;
- int entry = l.position();
- assert Util.isByte((entry - codeBuffer.position()) + shortSize) : "Dispacement too large for a short jmp";
- long offs = entry - codeBuffer.position();
- emitByte(0xEB);
- emitByte((int) ((offs - shortSize) & 0xFF));
- } else {
-
- l.addPatchAt(codeBuffer.position());
- emitByte(0xEB);
- emitByte(0);
- }
- }
-
- public final void leaq(CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0x8D);
- emitOperandHelper(dst, src);
- }
-
- public final void enter(int imm16, int imm8) {
- emitByte(0xC8);
- emitShort(imm16);
- emitByte(imm8);
- }
-
- public final void leave() {
- emitByte(0xC9);
- }
-
- public final void lock() {
- if ((C1XOptions.Atomics & 1) != 0) {
- // Emit either nothing, a NOP, or a NOP: prefix
- emitByte(0x90);
- } else {
- emitByte(0xF0);
- }
- }
-
- // Emit mfence instruction
- public final void mfence() {
- emitByte(0x0F);
- emitByte(0xAE);
- emitByte(0xF0);
- }
-
- public final void mov(CiRegister dst, CiRegister src) {
- movq(dst, src);
- }
-
- public final void movapd(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- int dstenc = dst.encoding;
- int srcenc = src.encoding;
- emitByte(0x66);
- if (dstenc < 8) {
- if (srcenc >= 8) {
- emitByte(Prefix.REXB);
- srcenc -= 8;
- }
- } else {
- if (srcenc < 8) {
- emitByte(Prefix.REXR);
- } else {
- emitByte(Prefix.REXRB);
- srcenc -= 8;
- }
- dstenc -= 8;
- }
- emitByte(0x0F);
- emitByte(0x28);
- emitByte(0xC0 | dstenc << 3 | srcenc);
- }
-
- public final void movaps(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- int dstenc = dst.encoding;
- int srcenc = src.encoding;
- if (dstenc < 8) {
- if (srcenc >= 8) {
- emitByte(Prefix.REXB);
- srcenc -= 8;
- }
- } else {
- if (srcenc < 8) {
- emitByte(Prefix.REXR);
- } else {
- emitByte(Prefix.REXRB);
- srcenc -= 8;
- }
- dstenc -= 8;
- }
- emitByte(0x0F);
- emitByte(0x28);
- emitByte(0xC0 | dstenc << 3 | srcenc);
- }
-
- public final void movb(CiRegister dst, CiAddress src) {
- prefix(src, dst); // , true)
- emitByte(0x8A);
- emitOperandHelper(dst, src);
- }
-
- public final void movb(CiAddress dst, int imm8) {
- prefix(dst);
- emitByte(0xC6);
- emitOperandHelper(rax, dst);
- emitByte(imm8);
- }
-
- public final void movb(CiAddress dst, CiRegister src) {
- assert src.isByte() : "must have byte register";
- prefix(dst, src); // , true)
- emitByte(0x88);
- emitOperandHelper(src, dst);
- }
-
- public final void movdl(CiRegister dst, CiRegister src) {
- if (dst.isFpu()) {
- assert !src.isFpu() : "does this hold?";
- emitByte(0x66);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x6E);
- emitByte(0xC0 | encode);
- } else if (src.isFpu()) {
- assert !dst.isFpu();
- emitByte(0x66);
- // swap src/dst to get correct prefix
- int encode = prefixAndEncode(src.encoding, dst.encoding);
- emitByte(0x0F);
- emitByte(0x7E);
- emitByte(0xC0 | encode);
- }
- }
-
- public final void movdqa(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
- emitByte(0x66);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x6F);
- emitOperandHelper(dst, src);
- }
-
- public final void movdqa(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- emitByte(0x66);
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x6F);
- emitByte(0xC0 | encode);
- }
-
- public final void movdqa(CiAddress dst, CiRegister src) {
- assert src.isFpu();
- emitByte(0x66);
- prefix(dst, src);
- emitByte(0x0F);
- emitByte(0x7F);
- emitOperandHelper(src, dst);
- }
-
- public final void movdqu(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
- emitByte(0xF3);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x6F);
- emitOperandHelper(dst, src);
- }
-
- public final void movdqu(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
-
- emitByte(0xF3);
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x6F);
- emitByte(0xC0 | encode);
- }
-
- public final void movdqu(CiAddress dst, CiRegister src) {
- assert src.isFpu();
-
- emitByte(0xF3);
- prefix(dst, src);
- emitByte(0x0F);
- emitByte(0x7F);
- emitOperandHelper(src, dst);
- }
-
- public final void movl(CiRegister dst, int imm32) {
- int encode = prefixAndEncode(dst.encoding);
- emitByte(0xB8 | encode);
- emitInt(imm32);
- }
-
- public final void movl(CiRegister dst, CiRegister src) {
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x8B);
- emitByte(0xC0 | encode);
- }
-
- public final void movl(CiRegister dst, CiAddress src) {
- prefix(src, dst);
- emitByte(0x8B);
- emitOperandHelper(dst, src);
- }
-
- public final void movl(CiAddress dst, int imm32) {
- prefix(dst);
- emitByte(0xC7);
- emitOperandHelper(rax, dst);
- emitInt(imm32);
- }
-
- public final void movl(CiAddress dst, CiRegister src) {
- prefix(dst, src);
- emitByte(0x89);
- emitOperandHelper(src, dst);
- }
-
- // New cpus require to use movsd and movss to avoid partial register stall
- // when loading from memory. But for old Opteron use movlpd instead of movsd.
- // The selection is done in Macromovdbl() and movflt().
- public final void movlpd(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
-
- emitByte(0x66);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x12);
- emitOperandHelper(dst, src);
-
- }
-
- public final void movq(CiRegister dst, CiAddress src) {
- if (dst.isFpu()) {
- emitByte(0xF3);
- prefixq(src, dst);
- emitByte(0x0F);
- emitByte(0x7E);
- emitOperandHelper(dst, src);
- } else {
- prefixq(src, dst);
- emitByte(0x8B);
- emitOperandHelper(dst, src);
- }
- }
-
- public final void movq(CiRegister dst, CiRegister src) {
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x8B);
- emitByte(0xC0 | encode);
- }
-
- public final void movq(CiAddress dst, CiRegister src) {
- if (src.isFpu()) {
- emitByte(0x66);
- prefixq(dst, src);
- emitByte(0x0F);
- emitByte(0xD6);
- emitOperandHelper(src, dst);
- } else {
- prefixq(dst, src);
- emitByte(0x89);
- emitOperandHelper(src, dst);
- }
- }
-
- public final void movsxb(CiRegister dst, CiAddress src) { // movsxb
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0xBE);
- emitOperandHelper(dst, src);
- }
-
- public final void movsxb(CiRegister dst, CiRegister src) { // movsxb
- int encode = prefixAndEncode(dst.encoding, src.encoding, true);
- emitByte(0x0F);
- emitByte(0xBE);
- emitByte(0xC0 | encode);
- }
-
- public final void movsd(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- emitByte(0xF2);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x10);
- emitByte(0xC0 | encode);
- }
-
- public final void movsd(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
- emitByte(0xF2);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x10);
- emitOperandHelper(dst, src);
- }
-
- public final void movsd(CiAddress dst, CiRegister src) {
- assert src.isFpu();
- emitByte(0xF2);
- prefix(dst, src);
- emitByte(0x0F);
- emitByte(0x11);
- emitOperandHelper(src, dst);
- }
-
- public final void movss(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- emitByte(0xF3);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x10);
- emitByte(0xC0 | encode);
- }
-
- public final void movss(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
- emitByte(0xF3);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x10);
- emitOperandHelper(dst, src);
- }
-
- public final void movss(CiAddress dst, CiRegister src) {
- assert src.isFpu();
- emitByte(0xF3);
- prefix(dst, src);
- emitByte(0x0F);
- emitByte(0x11);
- emitOperandHelper(src, dst);
- }
-
- public final void movswl(CiRegister dst, CiAddress src) {
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0xBF);
- emitOperandHelper(dst, src);
- }
-
- public final void movsxw(CiRegister dst, CiRegister src) { // movsxw
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0xBF);
- emitByte(0xC0 | encode);
- }
-
- public final void movsxw(CiRegister dst, CiAddress src) { // movsxw
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0xBF);
- emitOperandHelper(dst, src);
- }
-
- public final void movzxd(CiRegister dst, CiRegister src) { // movzxd
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x63);
- emitByte(0xC0 | encode);
- }
-
- public final void movzxd(CiRegister dst, CiAddress src) { // movzxd
- prefix(src, dst);
- emitByte(0x63);
- emitOperandHelper(dst, src);
- }
-
- public final void movw(CiAddress dst, int imm16) {
- emitByte(0x66); // switch to 16-bit mode
- prefix(dst);
- emitByte(0xC7);
- emitOperandHelper(rax, dst);
- emitShort(imm16);
- }
-
- public final void movw(CiRegister dst, CiAddress src) {
- emitByte(0x66);
- prefix(src, dst);
- emitByte(0x8B);
- emitOperandHelper(dst, src);
- }
-
- public final void movw(CiAddress dst, CiRegister src) {
- emitByte(0x66);
- prefix(dst, src);
- emitByte(0x89);
- emitOperandHelper(src, dst);
- }
-
- public final void movzxb(CiRegister dst, CiAddress src) { // movzxb
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0xB6);
- emitOperandHelper(dst, src);
- }
-
- public final void movzxb(CiRegister dst, CiRegister src) { // movzxb
- int encode = prefixAndEncode(dst.encoding, src.encoding, true);
- emitByte(0x0F);
- emitByte(0xB6);
- emitByte(0xC0 | encode);
- }
-
- public final void movzxl(CiRegister dst, CiAddress src) { // movzxw
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0xB7);
- emitOperandHelper(dst, src);
- }
-
- public final void movzxl(CiRegister dst, CiRegister src) { // movzxw
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0xB7);
- emitByte(0xC0 | encode);
- }
-
- public final void mull(CiAddress src) {
- prefix(src);
- emitByte(0xF7);
- emitOperandHelper(rsp, src);
- }
-
- public final void mulsd(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
- emitByte(0xF2);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x59);
- emitOperandHelper(dst, src);
- }
-
- public final void mulsd(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
-
- emitByte(0xF2);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x59);
- emitByte(0xC0 | encode);
- }
-
- public final void mulss(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
-
- emitByte(0xF3);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x59);
- emitOperandHelper(dst, src);
- }
-
- public final void mulss(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- emitByte(0xF3);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x59);
- emitByte(0xC0 | encode);
- }
-
- public final void negl(CiRegister dst) {
- int encode = prefixAndEncode(dst.encoding);
- emitByte(0xF7);
- emitByte(0xD8 | encode);
- }
-
- @Override
- public final void nop() {
- nop(1);
- }
-
- public void nop(int i) {
- if (C1XOptions.UseNormalNop) {
- assert i > 0 : " ";
- // The fancy nops aren't currently recognized by debuggers making it a
- // pain to disassemble code while debugging. If assert are on clearly
- // speed is not an issue so simply use the single byte traditional nop
- // to do alignment.
-
- for (; i > 0; i--) {
- emitByte(0x90);
- }
- return;
- }
-
- if (C1XOptions.UseAddressNop) {
- //
- // Using multi-bytes nops "0x0F 0x1F [Address]" for AMD.
- // 1: 0x90
- // 2: 0x66 0x90
- // 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding)
- // 4: 0x0F 0x1F 0x40 0x00
- // 5: 0x0F 0x1F 0x44 0x00 0x00
- // 6: 0x66 0x0F 0x1F 0x44 0x00 0x00
- // 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
- // 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
- // 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
- // 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
- // 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
-
- // The rest coding is AMD specific - use consecutive Address nops
-
- // 12: 0x66 0x0F 0x1F 0x44 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00
- // 13: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00
- // 14: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
- // 15: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
- // 16: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
- // Size prefixes (0x66) are added for larger sizes
-
- while (i >= 22) {
- i -= 11;
- emitByte(0x66); // size prefix
- emitByte(0x66); // size prefix
- emitByte(0x66); // size prefix
- addrNop8();
- }
- // Generate first nop for size between 21-12
- switch (i) {
- case 21:
- i -= 1;
- emitByte(0x66); // size prefix
- // fall through
- case 20:
- // fall through
- case 19:
- i -= 1;
- emitByte(0x66); // size prefix
- // fall through
- case 18:
- // fall through
- case 17:
- i -= 1;
- emitByte(0x66); // size prefix
- // fall through
- case 16:
- // fall through
- case 15:
- i -= 8;
- addrNop8();
- break;
- case 14:
- case 13:
- i -= 7;
- addrNop7();
- break;
- case 12:
- i -= 6;
- emitByte(0x66); // size prefix
- addrNop5();
- break;
- default:
- assert i < 12;
- }
-
- // Generate second nop for size between 11-1
- switch (i) {
- case 11:
- emitByte(0x66); // size prefix
- emitByte(0x66); // size prefix
- emitByte(0x66); // size prefix
- addrNop8();
- break;
- case 10:
- emitByte(0x66); // size prefix
- emitByte(0x66); // size prefix
- addrNop8();
- break;
- case 9:
- emitByte(0x66); // size prefix
- addrNop8();
- break;
- case 8:
- addrNop8();
- break;
- case 7:
- addrNop7();
- break;
- case 6:
- emitByte(0x66); // size prefix
- addrNop5();
- break;
- case 5:
- addrNop5();
- break;
- case 4:
- addrNop4();
- break;
- case 3:
- // Don't use "0x0F 0x1F 0x00" - need patching safe padding
- emitByte(0x66); // size prefix
- emitByte(0x66); // size prefix
- emitByte(0x90); // nop
- break;
- case 2:
- emitByte(0x66); // size prefix
- emitByte(0x90); // nop
- break;
- case 1:
- emitByte(0x90); // nop
- break;
- default:
- assert i == 0;
- }
- return;
- }
-
- // Using nops with size prefixes "0x66 0x90".
- // From AMD Optimization Guide:
- // 1: 0x90
- // 2: 0x66 0x90
- // 3: 0x66 0x66 0x90
- // 4: 0x66 0x66 0x66 0x90
- // 5: 0x66 0x66 0x90 0x66 0x90
- // 6: 0x66 0x66 0x90 0x66 0x66 0x90
- // 7: 0x66 0x66 0x66 0x90 0x66 0x66 0x90
- // 8: 0x66 0x66 0x66 0x90 0x66 0x66 0x66 0x90
- // 9: 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90
- // 10: 0x66 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90
- //
- while (i > 12) {
- i -= 4;
- emitByte(0x66); // size prefix
- emitByte(0x66);
- emitByte(0x66);
- emitByte(0x90); // nop
- }
- // 1 - 12 nops
- if (i > 8) {
- if (i > 9) {
- i -= 1;
- emitByte(0x66);
- }
- i -= 3;
- emitByte(0x66);
- emitByte(0x66);
- emitByte(0x90);
- }
- // 1 - 8 nops
- if (i > 4) {
- if (i > 6) {
- i -= 1;
- emitByte(0x66);
- }
- i -= 3;
- emitByte(0x66);
- emitByte(0x66);
- emitByte(0x90);
- }
- switch (i) {
- case 4:
- emitByte(0x66);
- emitByte(0x66);
- emitByte(0x66);
- emitByte(0x90);
- break;
- case 3:
- emitByte(0x66);
- emitByte(0x66);
- emitByte(0x90);
- break;
- case 2:
- emitByte(0x66);
- emitByte(0x90);
- break;
- case 1:
- emitByte(0x90);
- break;
- default:
- assert i == 0;
- }
- }
-
- public final void notl(CiRegister dst) {
- int encode = prefixAndEncode(dst.encoding);
- emitByte(0xF7);
- emitByte(0xD0 | encode);
- }
-
- public final void orl(CiAddress dst, int imm32) {
- prefix(dst);
- emitByte(0x81);
- emitOperandHelper(rcx, dst);
- emitInt(imm32);
- }
-
- public final void orl(CiRegister dst, int imm32) {
- prefix(dst);
- emitArith(0x81, 0xC8, dst, imm32);
- }
-
- public final void orl(CiRegister dst, CiAddress src) {
- prefix(src, dst);
- emitByte(0x0B);
- emitOperandHelper(dst, src);
- }
-
- public final void orl(CiRegister dst, CiRegister src) {
- prefixAndEncode(dst.encoding, src.encoding);
- emitArith(0x0B, 0xC0, dst, src);
- }
-
- // generic
- public final void pop(CiRegister dst) {
- int encode = prefixAndEncode(dst.encoding);
- emitByte(0x58 | encode);
- }
-
- public final void popl(CiAddress dst) {
- // NOTE: this will adjust stack by 8byte on 64bits
- prefix(dst);
- emitByte(0x8F);
- emitOperandHelper(rax, dst);
- }
-
- public final void prefetchPrefix(CiAddress src) {
- prefix(src);
- emitByte(0x0F);
- }
-
- public final void prefetchnta(CiAddress src) {
- prefetchPrefix(src);
- emitByte(0x18);
- emitOperandHelper(rax, src); // 0, src
- }
-
- public final void prefetchr(CiAddress src) {
- prefetchPrefix(src);
- emitByte(0x0D);
- emitOperandHelper(rax, src); // 0, src
- }
-
- public final void prefetcht0(CiAddress src) {
- prefetchPrefix(src);
- emitByte(0x18);
- emitOperandHelper(rcx, src); // 1, src
-
- }
-
- public final void prefetcht1(CiAddress src) {
- prefetchPrefix(src);
- emitByte(0x18);
- emitOperandHelper(rdx, src); // 2, src
- }
-
- public final void prefetcht2(CiAddress src) {
- prefetchPrefix(src);
- emitByte(0x18);
- emitOperandHelper(rbx, src); // 3, src
- }
-
- public final void prefetchw(CiAddress src) {
- prefetchPrefix(src);
- emitByte(0x0D);
- emitOperandHelper(rcx, src); // 1, src
- }
-
- public final void pshufd(CiRegister dst, CiRegister src, int mode) {
- assert dst.isFpu();
- assert src.isFpu();
- assert Util.isUByte(mode) : "invalid value";
-
- emitByte(0x66);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x70);
- emitByte(0xC0 | encode);
- emitByte(mode & 0xFF);
- }
-
- public final void pshufd(CiRegister dst, CiAddress src, int mode) {
- assert dst.isFpu();
- assert Util.isUByte(mode) : "invalid value";
-
- emitByte(0x66);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x70);
- emitOperandHelper(dst, src);
- emitByte(mode & 0xFF);
-
- }
-
- public final void pshuflw(CiRegister dst, CiRegister src, int mode) {
- assert dst.isFpu();
- assert src.isFpu();
- assert Util.isUByte(mode) : "invalid value";
-
- emitByte(0xF2);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x70);
- emitByte(0xC0 | encode);
- emitByte(mode & 0xFF);
- }
-
- public final void pshuflw(CiRegister dst, CiAddress src, int mode) {
- assert dst.isFpu();
- assert Util.isUByte(mode) : "invalid value";
-
- emitByte(0xF2);
- prefix(src, dst); // QQ new
- emitByte(0x0F);
- emitByte(0x70);
- emitOperandHelper(dst, src);
- emitByte(mode & 0xFF);
- }
-
- public final void psrlq(CiRegister dst, int shift) {
- assert dst.isFpu();
- // HMM Table D-1 says sse2 or mmx
-
- int encode = prefixqAndEncode(xmm2.encoding, dst.encoding);
- emitByte(0x66);
- emitByte(0x0F);
- emitByte(0x73);
- emitByte(0xC0 | encode);
- emitByte(shift);
- }
-
- public final void punpcklbw(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- emitByte(0x66);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x60);
- emitByte(0xC0 | encode);
- }
-
- public final void push(int imm32) {
- // in 64bits we push 64bits onto the stack but only
- // take a 32bit immediate
- emitByte(0x68);
- emitInt(imm32);
- }
-
- public final void push(CiRegister src) {
- int encode = prefixAndEncode(src.encoding);
- emitByte(0x50 | encode);
- }
-
- public final void pushf() {
- emitByte(0x9C);
- }
-
- public final void pushl(CiAddress src) {
- // Note this will push 64bit on 64bit
- prefix(src);
- emitByte(0xFF);
- emitOperandHelper(rsi, src);
- }
-
- public final void pxor(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
-
- emitByte(0x66);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0xEF);
- emitOperandHelper(dst, src);
- }
-
- public final void pxor(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
-
- emitByte(0x66);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0xEF);
- emitByte(0xC0 | encode);
-
- }
-
- public final void rcll(CiRegister dst, int imm8) {
- assert Util.isShiftCount(imm8) : "illegal shift count";
- int encode = prefixAndEncode(dst.encoding);
- if (imm8 == 1) {
- emitByte(0xD1);
- emitByte(0xD0 | encode);
- } else {
- emitByte(0xC1);
- emitByte(0xD0 | encode);
- emitByte(imm8);
- }
- }
-
- public final void pause() {
- emitByte(0xF3);
- emitByte(0x90);
- }
-
- // Copies data from [X86.rsi] to [X86.rdi] using X86.rcx heap words.
- public final void repeatMoveWords() {
- emitByte(0xF3);
- emitByte(Prefix.REXW);
- emitByte(0xA5);
- }
-
- // Copies data from [X86.rsi] to [X86.rdi] using X86.rcx bytes.
- public final void repeatMoveBytes() {
- emitByte(0xF3);
- emitByte(Prefix.REXW);
- emitByte(0xA4);
- }
-
- // sets X86.rcx pointer sized words with X86.rax, value at [edi]
- // generic
- public final void repSet() { // repSet
- emitByte(0xF3);
- // STOSQ
- emitByte(Prefix.REXW);
- emitByte(0xAB);
- }
-
- // scans X86.rcx pointer sized words at [edi] for occurance of X86.rax,
- // generic
- public final void repneScan() { // repneScan
- emitByte(0xF2);
- // SCASQ
- emitByte(Prefix.REXW);
- emitByte(0xAF);
- }
-
- // scans X86.rcx 4 byte words at [edi] for occurance of X86.rax,
- // generic
- public final void repneScanl() { // repneScan
- emitByte(0xF2);
- // SCASL
- emitByte(0xAF);
- }
-
- public final void ret(int imm16) {
- if (imm16 == 0) {
- emitByte(0xC3);
- } else {
- emitByte(0xC2);
- emitShort(imm16);
- }
- }
-
- public final void sarl(CiRegister dst, int imm8) {
- int encode = prefixAndEncode(dst.encoding);
- assert Util.isShiftCount(imm8) : "illegal shift count";
- if (imm8 == 1) {
- emitByte(0xD1);
- emitByte(0xF8 | encode);
- } else {
- emitByte(0xC1);
- emitByte(0xF8 | encode);
- emitByte(imm8);
- }
- }
-
- public final void sarl(CiRegister dst) {
- int encode = prefixAndEncode(dst.encoding);
- emitByte(0xD3);
- emitByte(0xF8 | encode);
- }
-
- public final void sbbl(CiAddress dst, int imm32) {
- prefix(dst);
- emitArithOperand(0x81, rbx, dst, imm32);
- }
-
- public final void sbbl(CiRegister dst, int imm32) {
- prefix(dst);
- emitArith(0x81, 0xD8, dst, imm32);
- }
-
- public final void sbbl(CiRegister dst, CiAddress src) {
- prefix(src, dst);
- emitByte(0x1B);
- emitOperandHelper(dst, src);
- }
-
- public final void sbbl(CiRegister dst, CiRegister src) {
- prefixAndEncode(dst.encoding, src.encoding);
- emitArith(0x1B, 0xC0, dst, src);
- }
-
- public final void setb(ConditionFlag cc, CiRegister dst) {
- assert 0 <= cc.value && cc.value < 16 : "illegal cc";
- int encode = prefixAndEncode(dst.encoding, true);
- emitByte(0x0F);
- emitByte(0x90 | cc.value);
- emitByte(0xC0 | encode);
- }
-
- public final void shll(CiRegister dst, int imm8) {
- assert Util.isShiftCount(imm8) : "illegal shift count";
- int encode = prefixAndEncode(dst.encoding);
- if (imm8 == 1) {
- emitByte(0xD1);
- emitByte(0xE0 | encode);
- } else {
- emitByte(0xC1);
- emitByte(0xE0 | encode);
- emitByte(imm8);
- }
- }
-
- public final void shll(CiRegister dst) {
- int encode = prefixAndEncode(dst.encoding);
- emitByte(0xD3);
- emitByte(0xE0 | encode);
- }
-
- public final void shrl(CiRegister dst, int imm8) {
- assert Util.isShiftCount(imm8) : "illegal shift count";
- int encode = prefixAndEncode(dst.encoding);
- emitByte(0xC1);
- emitByte(0xE8 | encode);
- emitByte(imm8);
- }
-
- public final void shrl(CiRegister dst) {
- int encode = prefixAndEncode(dst.encoding);
- emitByte(0xD3);
- emitByte(0xE8 | encode);
- }
-
- // copies a single word from [esi] to [edi]
- public final void smovl() {
- emitByte(0xA5);
- }
-
- public final void sqrtsd(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- // HMM Table D-1 says sse2
- // assert is64 || target.supportsSSE();
- emitByte(0xF2);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x51);
- emitByte(0xC0 | encode);
- }
-
- public final void subl(CiAddress dst, int imm32) {
- prefix(dst);
- if (Util.isByte(imm32)) {
- emitByte(0x83);
- emitOperandHelper(rbp, dst);
- emitByte(imm32 & 0xFF);
- } else {
- emitByte(0x81);
- emitOperandHelper(rbp, dst);
- emitInt(imm32);
- }
- }
-
- public final void subl(CiRegister dst, int imm32) {
- prefix(dst);
- emitArith(0x81, 0xE8, dst, imm32);
- }
-
- public final void subl(CiAddress dst, CiRegister src) {
- prefix(dst, src);
- emitByte(0x29);
- emitOperandHelper(src, dst);
- }
-
- public final void subl(CiRegister dst, CiAddress src) {
- prefix(src, dst);
- emitByte(0x2B);
- emitOperandHelper(dst, src);
- }
-
- public final void subl(CiRegister dst, CiRegister src) {
- prefixAndEncode(dst.encoding, src.encoding);
- emitArith(0x2B, 0xC0, dst, src);
- }
-
- public final void subsd(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- emitByte(0xF2);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x5C);
- emitByte(0xC0 | encode);
- }
-
- public final void subsd(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
-
- emitByte(0xF2);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x5C);
- emitOperandHelper(dst, src);
- }
-
- public final void subss(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- emitByte(0xF3);
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x5C);
- emitByte(0xC0 | encode);
- }
-
- public final void subss(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
-
- emitByte(0xF3);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x5C);
- emitOperandHelper(dst, src);
- }
-
- public final void testb(CiRegister dst, int imm8) {
- prefixAndEncode(dst.encoding, true);
- emitArithB(0xF6, 0xC0, dst, imm8);
- }
-
- public final void testl(CiRegister dst, int imm32) {
- // not using emitArith because test
- // doesn't support sign-extension of
- // 8bit operands
- int encode = dst.encoding;
- if (encode == 0) {
- emitByte(0xA9);
- } else {
- encode = prefixAndEncode(encode);
- emitByte(0xF7);
- emitByte(0xC0 | encode);
- }
- emitInt(imm32);
- }
-
- public final void testl(CiRegister dst, CiRegister src) {
- prefixAndEncode(dst.encoding, src.encoding);
- emitArith(0x85, 0xC0, dst, src);
- }
-
- public final void testl(CiRegister dst, CiAddress src) {
- prefix(src, dst);
- emitByte(0x85);
- emitOperandHelper(dst, src);
- }
-
- public final void ucomisd(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
- emitByte(0x66);
- ucomiss(dst, src);
- }
-
- public final void ucomisd(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- emitByte(0x66);
- ucomiss(dst, src);
- }
-
- public final void ucomiss(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
-
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x2E);
- emitOperandHelper(dst, src);
- }
-
- public final void ucomiss(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x2E);
- emitByte(0xC0 | encode);
- }
-
- public final void xaddl(CiAddress dst, CiRegister src) {
- assert src.isFpu();
-
- prefix(dst, src);
- emitByte(0x0F);
- emitByte(0xC1);
- emitOperandHelper(src, dst);
- }
-
- public final void xchgl(CiRegister dst, CiAddress src) { // xchg
- prefix(src, dst);
- emitByte(0x87);
- emitOperandHelper(dst, src);
- }
-
- public final void xchgl(CiRegister dst, CiRegister src) {
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x87);
- emitByte(0xc0 | encode);
- }
-
- public final void xorl(CiRegister dst, int imm32) {
- prefix(dst);
- emitArith(0x81, 0xF0, dst, imm32);
- }
-
- public final void xorl(CiRegister dst, CiAddress src) {
- prefix(src, dst);
- emitByte(0x33);
- emitOperandHelper(dst, src);
- }
-
- public final void xorl(CiRegister dst, CiRegister src) {
- prefixAndEncode(dst.encoding, src.encoding);
- emitArith(0x33, 0xC0, dst, src);
- }
-
- public final void xorpd(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- assert src.isFpu();
- emitByte(0x66);
- xorps(dst, src);
- }
-
- public final void xorpd(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
-
- emitByte(0x66);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x57);
- emitOperandHelper(dst, src);
- }
-
- public final void xorps(CiRegister dst, CiRegister src) {
-
- assert dst.isFpu();
- int encode = prefixAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x57);
- emitByte(0xC0 | encode);
- }
-
- public final void xorps(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
-
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x57);
- emitOperandHelper(dst, src);
- }
-
- // 32bit only pieces of the assembler
-
- public final void decl(CiRegister dst) {
- // Don't use it directly. Use Macrodecrementl() instead.
- // Use two-byte form (one-byte form is a REX prefix in 64-bit mode)
- int encode = prefixAndEncode(dst.encoding);
- emitByte(0xFF);
- emitByte(0xC8 | encode);
- }
-
- public final void incl(CiRegister dst) {
- // Don't use it directly. Use Macroincrementl() instead.
- // Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
- int encode = prefixAndEncode(dst.encoding);
- emitByte(0xFF);
- emitByte(0xC0 | encode);
- }
-
- int prefixAndEncode(int regEnc) {
- return prefixAndEncode(regEnc, false);
- }
-
- int prefixAndEncode(int regEnc, boolean byteinst) {
- if (regEnc >= 8) {
- emitByte(Prefix.REXB);
- regEnc -= 8;
- } else if (byteinst && regEnc >= 4) {
- emitByte(Prefix.REX);
- }
- return regEnc;
- }
-
- int prefixqAndEncode(int regEnc) {
- if (regEnc < 8) {
- emitByte(Prefix.REXW);
- } else {
- emitByte(Prefix.REXWB);
- regEnc -= 8;
- }
- return regEnc;
- }
-
- int prefixAndEncode(int dstEnc, int srcEnc) {
- return prefixAndEncode(dstEnc, srcEnc, false);
- }
-
- int prefixAndEncode(int dstEnc, int srcEnc, boolean byteinst) {
- if (dstEnc < 8) {
- if (srcEnc >= 8) {
- emitByte(Prefix.REXB);
- srcEnc -= 8;
- } else if (byteinst && srcEnc >= 4) {
- emitByte(Prefix.REX);
- }
- } else {
- if (srcEnc < 8) {
- emitByte(Prefix.REXR);
- } else {
- emitByte(Prefix.REXRB);
- srcEnc -= 8;
- }
- dstEnc -= 8;
- }
- return dstEnc << 3 | srcEnc;
- }
-
- /**
- * Creates prefix and the encoding of the lower 6 bits of the ModRM-Byte. It emits an operand prefix. If the given
- * operands exceed 3 bits, the 4th bit is encoded in the prefix.
- *
- * @param regEnc the encoding of the register part of the ModRM-Byte
- * @param rmEnc the encoding of the r/m part of the ModRM-Byte
- * @return the lower 6 bits of the ModRM-Byte that should be emitted
- */
- private int prefixqAndEncode(int regEnc, int rmEnc) {
- if (regEnc < 8) {
- if (rmEnc < 8) {
- emitByte(Prefix.REXW);
- } else {
- emitByte(Prefix.REXWB);
- rmEnc -= 8;
- }
- } else {
- if (rmEnc < 8) {
- emitByte(Prefix.REXWR);
- } else {
- emitByte(Prefix.REXWRB);
- rmEnc -= 8;
- }
- regEnc -= 8;
- }
- return regEnc << 3 | rmEnc;
- }
-
- private void prefix(CiRegister reg) {
- if (reg.encoding >= 8) {
- emitByte(Prefix.REXB);
- }
- }
-
- private void prefix(CiAddress adr) {
- if (adr.base().encoding >= MinEncodingNeedsRex) {
- if (adr.index().encoding >= MinEncodingNeedsRex) {
- emitByte(Prefix.REXXB);
- } else {
- emitByte(Prefix.REXB);
- }
- } else {
- if (adr.index().encoding >= MinEncodingNeedsRex) {
- emitByte(Prefix.REXX);
- }
- }
- }
-
- private void prefixq(CiAddress adr) {
- if (adr.base().encoding >= MinEncodingNeedsRex) {
- if (adr.index().encoding >= MinEncodingNeedsRex) {
- emitByte(Prefix.REXWXB);
- } else {
- emitByte(Prefix.REXWB);
- }
- } else {
- if (adr.index().encoding >= MinEncodingNeedsRex) {
- emitByte(Prefix.REXWX);
- } else {
- emitByte(Prefix.REXW);
- }
- }
- }
-
- private void prefix(CiAddress adr, CiRegister reg) {
- if (reg.encoding < 8) {
- if (adr.base().encoding >= MinEncodingNeedsRex) {
- if (adr.index().encoding >= MinEncodingNeedsRex) {
- emitByte(Prefix.REXXB);
- } else {
- emitByte(Prefix.REXB);
- }
- } else {
- if (adr.index().encoding >= MinEncodingNeedsRex) {
- emitByte(Prefix.REXX);
- } else if (reg.encoding >= 4) {
- emitByte(Prefix.REX);
- }
- }
- } else {
- if (adr.base().encoding >= MinEncodingNeedsRex) {
- if (adr.index().encoding >= MinEncodingNeedsRex) {
- emitByte(Prefix.REXRXB);
- } else {
- emitByte(Prefix.REXRB);
- }
- } else {
- if (adr.index().encoding >= MinEncodingNeedsRex) {
- emitByte(Prefix.REXRX);
- } else {
- emitByte(Prefix.REXR);
- }
- }
- }
- }
-
- private void prefixq(CiAddress adr, CiRegister src) {
- if (src.encoding < 8) {
- if (adr.base().encoding >= MinEncodingNeedsRex) {
- if (adr.index().encoding >= MinEncodingNeedsRex) {
- emitByte(Prefix.REXWXB);
- } else {
- emitByte(Prefix.REXWB);
- }
- } else {
- if (adr.index().encoding >= MinEncodingNeedsRex) {
- emitByte(Prefix.REXWX);
- } else {
- emitByte(Prefix.REXW);
- }
- }
- } else {
- if (adr.base().encoding >= MinEncodingNeedsRex) {
- if (adr.index().encoding >= MinEncodingNeedsRex) {
- emitByte(Prefix.REXWRXB);
- } else {
- emitByte(Prefix.REXWRB);
- }
- } else {
- if (adr.index().encoding >= MinEncodingNeedsRex) {
- emitByte(Prefix.REXWRX);
- } else {
- emitByte(Prefix.REXWR);
- }
- }
- }
- }
-
- public final void addq(CiAddress dst, int imm32) {
- prefixq(dst);
- emitArithOperand(0x81, rax, dst, imm32);
- }
-
- public final void addq(CiAddress dst, CiRegister src) {
- prefixq(dst, src);
- emitByte(0x01);
- emitOperandHelper(src, dst);
- }
-
- public final void addq(CiRegister dst, int imm32) {
- prefixqAndEncode(dst.encoding);
- emitArith(0x81, 0xC0, dst, imm32);
- }
-
- public final void addq(CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0x03);
- emitOperandHelper(dst, src);
- }
-
- public final void addq(CiRegister dst, CiRegister src) {
- prefixqAndEncode(dst.encoding, src.encoding);
- emitArith(0x03, 0xC0, dst, src);
- }
-
- public final void andq(CiRegister dst, int imm32) {
- prefixqAndEncode(dst.encoding);
- emitArith(0x81, 0xE0, dst, imm32);
- }
-
- public final void andq(CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0x23);
- emitOperandHelper(dst, src);
- }
-
- public final void andq(CiRegister dst, CiRegister src) {
- prefixqAndEncode(dst.encoding, src.encoding);
- emitArith(0x23, 0xC0, dst, src);
- }
-
- public final void bswapq(CiRegister reg) {
- int encode = prefixqAndEncode(reg.encoding);
- emitByte(0x0F);
- emitByte(0xC8 | encode);
- }
-
- public final void cdqq() {
- emitByte(Prefix.REXW);
- emitByte(0x99);
- }
-
- public final void cmovq(ConditionFlag cc, CiRegister dst, CiRegister src) {
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x40 | cc.value);
- emitByte(0xC0 | encode);
- }
-
- public final void cmovq(ConditionFlag cc, CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0x0F);
- emitByte(0x40 | cc.value);
- emitOperandHelper(dst, src);
- }
-
- public final void cmpq(CiAddress dst, int imm32) {
- prefixq(dst);
- emitByte(0x81);
- emitOperandHelper(rdi, dst);
- emitInt(imm32);
- }
-
- public final void cmpq(CiRegister dst, int imm32) {
- prefixqAndEncode(dst.encoding);
- emitArith(0x81, 0xF8, dst, imm32);
- }
-
- public final void cmpq(CiAddress dst, CiRegister src) {
- prefixq(dst, src);
- emitByte(0x3B);
- emitOperandHelper(src, dst);
- }
-
- public final void cmpq(CiRegister dst, CiRegister src) {
- prefixqAndEncode(dst.encoding, src.encoding);
- emitArith(0x3B, 0xC0, dst, src);
- }
-
- public final void cmpq(CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0x3B);
- emitOperandHelper(dst, src);
- }
-
- public final void cmpxchgq(CiRegister reg, CiAddress adr) {
- prefixq(adr, reg);
- emitByte(0x0F);
- emitByte(0xB1);
- emitOperandHelper(reg, adr);
- }
-
- public final void cvtsi2sdq(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- emitByte(0xF2);
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x2A);
- emitByte(0xC0 | encode);
- }
-
- public final void cvtsi2ssq(CiRegister dst, CiRegister src) {
- assert dst.isFpu();
- emitByte(0xF3);
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x2A);
- emitByte(0xC0 | encode);
- }
-
- public final void cvttsd2siq(CiRegister dst, CiRegister src) {
- assert src.isFpu();
- emitByte(0xF2);
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x2C);
- emitByte(0xC0 | encode);
- }
-
- public final void cvttss2siq(CiRegister dst, CiRegister src) {
- assert src.isFpu();
- emitByte(0xF3);
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x2C);
- emitByte(0xC0 | encode);
- }
-
- public final void decq(CiRegister dst) {
- // Don't use it directly. Use Macrodecrementq() instead.
- // Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
- int encode = prefixqAndEncode(dst.encoding);
- emitByte(0xFF);
- emitByte(0xC8 | encode);
- }
-
- public final void decq(CiAddress dst) {
- // Don't use it directly. Use Macrodecrementq() instead.
- prefixq(dst);
- emitByte(0xFF);
- emitOperandHelper(rcx, dst);
- }
-
- public final void divq(CiRegister src) {
- int encode = prefixqAndEncode(src.encoding);
- emitByte(0xF7);
- emitByte(0xF0 | encode);
- }
-
- public final void idivq(CiRegister src) {
- int encode = prefixqAndEncode(src.encoding);
- emitByte(0xF7);
- emitByte(0xF8 | encode);
- }
-
- public final void imulq(CiRegister dst, CiRegister src) {
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0xAF);
- emitByte(0xC0 | encode);
- }
-
- public final void imulq(CiRegister dst, CiRegister src, int value) {
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- if (Util.isByte(value)) {
- emitByte(0x6B);
- emitByte(0xC0 | encode);
- emitByte(value);
- } else {
- emitByte(0x69);
- emitByte(0xC0 | encode);
- emitInt(value);
- }
- }
-
- public final void incq(CiRegister dst) {
- // Don't use it directly. Use Macroincrementq() instead.
- // Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
- int encode = prefixqAndEncode(dst.encoding);
- emitByte(0xFF);
- emitByte(0xC0 | encode);
- }
-
- public final void incq(CiAddress dst) {
- // Don't use it directly. Use Macroincrementq() instead.
- prefixq(dst);
- emitByte(0xFF);
- emitOperandHelper(rax, dst);
- }
-
- public final void movq(CiRegister dst, long imm64) {
- int encode = prefixqAndEncode(dst.encoding);
- emitByte(0xB8 | encode);
- emitLong(imm64);
- }
-
- public final void movdq(CiRegister dst, CiRegister src) {
-
- // table D-1 says MMX/SSE2
- emitByte(0x66);
-
- if (dst.isFpu()) {
- assert dst.isFpu();
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0x6E);
- emitByte(0xC0 | encode);
- } else if (src.isFpu()) {
-
- // swap src/dst to get correct prefix
- int encode = prefixqAndEncode(src.encoding, dst.encoding);
- emitByte(0x0F);
- emitByte(0x7E);
- emitByte(0xC0 | encode);
- } else {
- Util.shouldNotReachHere();
- }
- }
-
- public final void movsbq(CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0x0F);
- emitByte(0xBE);
- emitOperandHelper(dst, src);
- }
-
- public final void movsbq(CiRegister dst, CiRegister src) {
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0xBE);
- emitByte(0xC0 | encode);
- }
-
- public final void movslq(CiRegister dst, int imm32) {
- // dbx shows movslq(X86.rcx, 3) as movq $0x0000000049000000,(%X86.rbx)
- // and movslq(X86.r8, 3); as movl $0x0000000048000000,(%X86.rbx)
- // as a result we shouldn't use until tested at runtime...
- Util.shouldNotReachHere();
-
- int encode = prefixqAndEncode(dst.encoding);
- emitByte(0xC7 | encode);
- emitInt(imm32);
- }
-
- public final void movslq(CiAddress dst, int imm32) {
- prefixq(dst);
- emitByte(0xC7);
- emitOperandHelper(rax, dst);
- emitInt(imm32);
- }
-
- public final void movslq(CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0x63);
- emitOperandHelper(dst, src);
- }
-
- public final void movslq(CiRegister dst, CiRegister src) {
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x63);
- emitByte(0xC0 | encode);
- }
-
- public final void movswq(CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0x0F);
- emitByte(0xBF);
- emitOperandHelper(dst, src);
- }
-
- public final void movswq(CiRegister dst, CiRegister src) {
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0xBF);
- emitByte(0xC0 | encode);
- }
-
- public final void movzbq(CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0x0F);
- emitByte(0xB6);
- emitOperandHelper(dst, src);
- }
-
- public final void movzbq(CiRegister dst, CiRegister src) {
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0xB6);
- emitByte(0xC0 | encode);
- }
-
- public final void movzwq(CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0x0F);
- emitByte(0xB7);
- emitOperandHelper(dst, src);
- }
-
- public final void movzwq(CiRegister dst, CiRegister src) {
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x0F);
- emitByte(0xB7);
- emitByte(0xC0 | encode);
- }
-
- public final void negq(CiRegister dst) {
- int encode = prefixqAndEncode(dst.encoding);
- emitByte(0xF7);
- emitByte(0xD8 | encode);
- }
-
- public final void notq(CiRegister dst) {
- int encode = prefixqAndEncode(dst.encoding);
- emitByte(0xF7);
- emitByte(0xD0 | encode);
- }
-
- public final void orq(CiAddress dst, int imm32) {
- prefixq(dst);
- emitByte(0x81);
- emitOperandHelper(rcx, dst);
- emitInt(imm32);
- }
-
- public final void orq(CiRegister dst, int imm32) {
- prefixqAndEncode(dst.encoding);
- emitArith(0x81, 0xC8, dst, imm32);
- }
-
- public final void orq(CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0x0B);
- emitOperandHelper(dst, src);
- }
-
- public final void orq(CiRegister dst, CiRegister src) {
- prefixqAndEncode(dst.encoding, src.encoding);
- emitArith(0x0B, 0xC0, dst, src);
- }
-
- public final void popq(CiAddress dst) {
- prefixq(dst);
- emitByte(0x8F);
- emitOperandHelper(rax, dst);
- }
-
- public final void pushq(CiAddress src) {
- prefixq(src);
- emitByte(0xFF);
- emitOperandHelper(rsi, src);
- }
-
- public final void rclq(CiRegister dst, int imm8) {
- assert Util.isShiftCount(imm8 >> 1) : "illegal shift count";
- int encode = prefixqAndEncode(dst.encoding);
- if (imm8 == 1) {
- emitByte(0xD1);
- emitByte(0xD0 | encode);
- } else {
- emitByte(0xC1);
- emitByte(0xD0 | encode);
- emitByte(imm8);
- }
- }
-
- public final void sarq(CiRegister dst, int imm8) {
- assert Util.isShiftCount(imm8 >> 1) : "illegal shift count";
- int encode = prefixqAndEncode(dst.encoding);
- if (imm8 == 1) {
- emitByte(0xD1);
- emitByte(0xF8 | encode);
- } else {
- emitByte(0xC1);
- emitByte(0xF8 | encode);
- emitByte(imm8);
- }
- }
-
- public final void sarq(CiRegister dst) {
- int encode = prefixqAndEncode(dst.encoding);
- emitByte(0xD3);
- emitByte(0xF8 | encode);
- }
-
- public final void shlq(CiRegister dst, int imm8) {
- assert Util.isShiftCount(imm8 >> 1) : "illegal shift count";
- int encode = prefixqAndEncode(dst.encoding);
- if (imm8 == 1) {
- emitByte(0xD1);
- emitByte(0xE0 | encode);
- } else {
- emitByte(0xC1);
- emitByte(0xE0 | encode);
- emitByte(imm8);
- }
- }
-
- public final void shlq(CiRegister dst) {
- int encode = prefixqAndEncode(dst.encoding);
- emitByte(0xD3);
- emitByte(0xE0 | encode);
- }
-
- public final void shrq(CiRegister dst, int imm8) {
- assert Util.isShiftCount(imm8 >> 1) : "illegal shift count";
- int encode = prefixqAndEncode(dst.encoding);
- emitByte(0xC1);
- emitByte(0xE8 | encode);
- emitByte(imm8);
- }
-
- public final void shrq(CiRegister dst) {
- int encode = prefixqAndEncode(dst.encoding);
- emitByte(0xD3);
- emitByte(0xE8 | encode);
- }
-
- public final void sqrtsd(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
-
- emitByte(0xF2);
- prefix(src, dst);
- emitByte(0x0F);
- emitByte(0x51);
- emitOperandHelper(dst, src);
- }
-
- public final void subq(CiAddress dst, int imm32) {
- prefixq(dst);
- if (Util.isByte(imm32)) {
- emitByte(0x83);
- emitOperandHelper(rbp, dst);
- emitByte(imm32 & 0xFF);
- } else {
- emitByte(0x81);
- emitOperandHelper(rbp, dst);
- emitInt(imm32);
- }
- }
-
- public final void subq(CiRegister dst, int imm32) {
- prefixqAndEncode(dst.encoding);
- emitArith(0x81, 0xE8, dst, imm32);
- }
-
- public final void subq(CiAddress dst, CiRegister src) {
- prefixq(dst, src);
- emitByte(0x29);
- emitOperandHelper(src, dst);
- }
-
- public final void subq(CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0x2B);
- emitOperandHelper(dst, src);
- }
-
- public final void subq(CiRegister dst, CiRegister src) {
- prefixqAndEncode(dst.encoding, src.encoding);
- emitArith(0x2B, 0xC0, dst, src);
- }
-
- public final void testq(CiRegister dst, int imm32) {
- // not using emitArith because test
- // doesn't support sign-extension of
- // 8bit operands
- int encode = dst.encoding;
- if (encode == 0) {
- emitByte(Prefix.REXW);
- emitByte(0xA9);
- } else {
- encode = prefixqAndEncode(encode);
- emitByte(0xF7);
- emitByte(0xC0 | encode);
- }
- emitInt(imm32);
- }
-
- public final void testq(CiRegister dst, CiRegister src) {
- prefixqAndEncode(dst.encoding, src.encoding);
- emitArith(0x85, 0xC0, dst, src);
- }
-
- public final void xaddq(CiAddress dst, CiRegister src) {
- prefixq(dst, src);
- emitByte(0x0F);
- emitByte(0xC1);
- emitOperandHelper(src, dst);
- }
-
- public final void xchgq(CiRegister dst, CiAddress src) {
- prefixq(src, dst);
- emitByte(0x87);
- emitOperandHelper(dst, src);
- }
-
- public final void xchgq(CiRegister dst, CiRegister src) {
- int encode = prefixqAndEncode(dst.encoding, src.encoding);
- emitByte(0x87);
- emitByte(0xc0 | encode);
- }
-
- public final void xorq(CiRegister dst, CiRegister src) {
- prefixqAndEncode(dst.encoding, src.encoding);
- emitArith(0x33, 0xC0, dst, src);
- }
-
- public final void xorq(CiRegister dst, CiAddress src) {
-
- prefixq(src, dst);
- emitByte(0x33);
- emitOperandHelper(dst, src);
-
- }
-
- public final void membar(int barriers) {
- if (target.isMP) {
- // We only have to handle StoreLoad
- if ((barriers & STORE_LOAD) != 0) {
- // All usable chips support "locked" instructions which suffice
- // as barriers, and are much faster than the alternative of
- // using cpuid instruction. We use here a locked add [rsp],0.
- // This is conveniently otherwise a no-op except for blowing
- // flags.
- // Any change to this code may need to revisit other places in
- // the code where this idiom is used, in particular the
- // orderAccess code.
- lock();
- addl(new CiAddress(CiKind.Word, RSP, 0), 0); // Assert the lock# signal here
- }
- }
- }
-
- @Override
- public final void patchJumpTarget(int branch, int branchTarget) {
- int op = codeBuffer.getByte(branch);
- assert op == 0xE8 // call
- || op == 0x00 // jump table entry
- || op == 0xE9 // jmp
- || op == 0xEB // short jmp
- || (op & 0xF0) == 0x70 // short jcc
- || op == 0x0F && (codeBuffer.getByte(branch + 1) & 0xF0) == 0x80 // jcc
- : "Invalid opcode at patch point branch=" + branch + ", branchTarget=" + branchTarget + ", op=" + op;
-
- if (op == 0x00) {
- int offsetToJumpTableBase = codeBuffer.getShort(branch + 1);
- int jumpTableBase = branch - offsetToJumpTableBase;
- int imm32 = branchTarget - jumpTableBase;
- codeBuffer.emitInt(imm32, branch);
- } else if (op == 0xEB || (op & 0xF0) == 0x70) {
-
- // short offset operators (jmp and jcc)
- int imm8 = branchTarget - (branch + 2);
- codeBuffer.emitByte(imm8, branch + 1);
-
- } else {
-
- int off = 1;
- if (op == 0x0F) {
- off = 2;
- }
-
- int imm32 = branchTarget - (branch + 4 + off);
- codeBuffer.emitInt(imm32, branch + off);
- }
- }
-
- @Override
- public void nullCheck(CiRegister r) {
- testl(AMD64.rax, new CiAddress(CiKind.Word, r.asValue(Word), 0));
- }
-
- @Override
- public void align(int modulus) {
- if (codeBuffer.position() % modulus != 0) {
- nop(modulus - (codeBuffer.position() % modulus));
- }
- }
-}
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64Backend.java
--- a/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64Backend.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64Backend.java Fri May 13 17:09:20 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,9 @@
import static com.sun.c1x.C1XCompilation.*;
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
import com.sun.c1x.*;
-import com.sun.c1x.asm.*;
import com.sun.c1x.gen.*;
import com.sun.c1x.globalstub.*;
import com.sun.c1x.lir.*;
@@ -69,7 +70,7 @@
}
@Override
public AbstractAssembler newAssembler(RiRegisterConfig registerConfig) {
- return new AMD64MacroAssembler.WithCompiler(compiler, registerConfig);
+ return new AMD64MacroAssembler(compiler.target, registerConfig);
}
@Override
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64GlobalStubEmitter.java
--- a/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64GlobalStubEmitter.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64GlobalStubEmitter.java Fri May 13 17:09:20 2011 -0700
@@ -26,10 +26,12 @@
import java.util.*;
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.*;
import com.sun.c1x.*;
import com.sun.c1x.asm.*;
import com.sun.c1x.globalstub.*;
-import com.sun.c1x.target.amd64.AMD64Assembler.ConditionFlag;
import com.sun.cri.ci.*;
import com.sun.cri.ci.CiRegister.RegisterFlag;
import com.sun.cri.ri.*;
@@ -52,6 +54,7 @@
private static final CiRegister negateArgument = AMD64.xmm0;
private static final CiRegister negateTemp = AMD64.xmm1;
+ private TargetMethodAssembler tasm;
private AMD64MacroAssembler asm;
private final CiTarget target;
private int argsSize;
@@ -73,7 +76,8 @@
}
private void reset(CiKind resultKind, CiKind[] argTypes) {
- asm = new AMD64MacroAssembler.WithCompiler(compiler, compiler.globalStubRegisterConfig);
+ asm = new AMD64MacroAssembler(compiler.target, compiler.globalStubRegisterConfig);
+ tasm = new TargetMethodAssembler(asm);
saveSize = 0;
argsSize = 0;
argOffsets = new int[argTypes.length];
@@ -98,7 +102,7 @@
reset(runtimeCall.resultKind, runtimeCall.arguments);
emitStandardForward(null, runtimeCall);
String name = "stub-" + runtimeCall;
- CiTargetMethod targetMethod = asm.finishTargetMethod(name, runtime, registerRestoreEpilogueOffset, true);
+ CiTargetMethod targetMethod = tasm.finishTargetMethod(name, runtime, registerRestoreEpilogueOffset, true);
Object stubObject = runtime.registerGlobalStub(targetMethod, name);
return new GlobalStub(null, runtimeCall.resultKind, stubObject, argsSize, argOffsets, resultOffset);
}
@@ -128,7 +132,7 @@
}
String name = "stub-" + stub;
- CiTargetMethod targetMethod = asm.finishTargetMethod(name, runtime, registerRestoreEpilogueOffset, true);
+ CiTargetMethod targetMethod = tasm.finishTargetMethod(name, runtime, registerRestoreEpilogueOffset, true);
Object stubObject = runtime.registerGlobalStub(targetMethod, name);
return new GlobalStub(stub, stub.resultKind, stubObject, argsSize, argOffsets, resultOffset);
}
@@ -171,6 +175,7 @@
compilation.frameMap().setFrameSize(frameSize());
AMD64LIRAssembler assembler = new AMD64LIRAssembler(compilation);
asm = assembler.masm;
+ tasm = assembler.tasm;
ArrayList allocatableRegisters = new ArrayList(Arrays.asList(compiler.globalStubRegisterConfig.getCategorizedAllocatableRegisters().get(RegisterFlag.CPU)));
for (XirTemp t : template.temps) {
@@ -237,7 +242,7 @@
assert template.marks.length == 0 : "marks not supported in global stubs";
assembler.emitXirInstructions(null, template.fastPath, labels, operands, null);
epilogue();
- CiTargetMethod targetMethod = asm.finishTargetMethod(template.name, runtime, registerRestoreEpilogueOffset, true);
+ CiTargetMethod targetMethod = tasm.finishTargetMethod(template.name, runtime, registerRestoreEpilogueOffset, true);
Object stubObject = runtime.registerGlobalStub(targetMethod, template.name);
return new GlobalStub(null, template.resultOperand.kind, stubObject, argsSize, argOffsets, resultOffset);
}
@@ -263,14 +268,14 @@
private void emitDNEG() {
negatePrologue();
- asm.movsd(negateTemp, asm.recordDataReferenceInCode(CiConstant.forLong(DoubleSignFlip)));
+ asm.movsd(negateTemp, tasm.recordDataReferenceInCode(CiConstant.forLong(DoubleSignFlip)));
asm.xorpd(negateArgument, negateTemp);
negateEpilogue();
}
private void emitFNEG() {
negatePrologue();
- asm.movsd(negateTemp, asm.recordDataReferenceInCode(CiConstant.forLong(FloatSignFlip)));
+ asm.movsd(negateTemp, tasm.recordDataReferenceInCode(CiConstant.forLong(FloatSignFlip)));
asm.xorps(negateArgument, negateTemp);
negateEpilogue();
}
@@ -304,9 +309,9 @@
private void emitCOMISSD(boolean isDouble, boolean isInt) {
convertPrologue();
if (isDouble) {
- asm.ucomisd(convertArgument, asm.recordDataReferenceInCode(CiConstant.DOUBLE_0));
+ asm.ucomisd(convertArgument, tasm.recordDataReferenceInCode(CiConstant.DOUBLE_0));
} else {
- asm.ucomiss(convertArgument, asm.recordDataReferenceInCode(CiConstant.FLOAT_0));
+ asm.ucomiss(convertArgument, tasm.recordDataReferenceInCode(CiConstant.FLOAT_0));
}
Label nan = new Label();
Label ret = new Label();
@@ -372,7 +377,7 @@
index++;
}
- asm.setFrameSize(frameSize());
+ tasm.setFrameSize(frameSize());
this.savedAllRegisters = false;
}
@@ -385,7 +390,7 @@
asm.nop(entryCodeOffset);
}
asm.subq(AMD64.rsp, frameSize());
- asm.setFrameSize(frameSize());
+ tasm.setFrameSize(frameSize());
int frameToCSA = 0;
asm.save(csa, frameToCSA);
this.savedAllRegisters = true;
@@ -426,7 +431,10 @@
}
// Call to the runtime
- asm.directCall(call, null);
+ int before = asm.codeBuffer.position();
+ asm.call();
+ int after = asm.codeBuffer.position();
+ tasm.recordDirectCall(before, after, call, null);
if (call.resultKind != CiKind.Void) {
CiRegister returnRegister = compiler.globalStubRegisterConfig.getReturnRegister(call.resultKind);
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRAssembler.java
--- a/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRAssembler.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRAssembler.java Fri May 13 17:09:20 2011 -0700
@@ -31,30 +31,25 @@
import java.util.*;
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.*;
import com.sun.c1x.*;
-import com.sun.c1x.asm.*;
import com.sun.c1x.debug.*;
-import com.sun.c1x.gen.LIRGenerator.DeoptimizationStub;
+import com.sun.c1x.gen.LIRGenerator.*;
+import com.sun.c1x.globalstub.*;
import com.sun.c1x.ir.*;
-import com.sun.c1x.lir.FrameMap.StackBlock;
import com.sun.c1x.lir.*;
-import com.sun.c1x.target.amd64.AMD64Assembler.ConditionFlag;
+import com.sun.c1x.lir.FrameMap.*;
import com.sun.c1x.util.*;
import com.sun.cri.ci.*;
-import com.sun.cri.ci.CiAddress.Scale;
-import com.sun.cri.ci.CiTargetMethod.JumpTable;
-import com.sun.cri.ci.CiTargetMethod.Mark;
+import com.sun.cri.ci.CiAddress.*;
+import com.sun.cri.ci.CiTargetMethod.*;
import com.sun.cri.xir.*;
-import com.sun.cri.xir.CiXirAssembler.RuntimeCallInformation;
-import com.sun.cri.xir.CiXirAssembler.XirInstruction;
-import com.sun.cri.xir.CiXirAssembler.XirLabel;
-import com.sun.cri.xir.CiXirAssembler.XirMark;
+import com.sun.cri.xir.CiXirAssembler.*;
/**
* This class implements the x86-specific code generation for LIR.
- *
- * @author Thomas Wuerthinger
- * @author Ben L. Titzer
*/
public final class AMD64LIRAssembler extends LIRAssembler {
@@ -71,7 +66,7 @@
public AMD64LIRAssembler(C1XCompilation compilation) {
super(compilation);
- masm = (AMD64MacroAssembler) compilation.masm();
+ masm = (AMD64MacroAssembler) asm;
target = compilation.target;
wordSize = target.wordSize;
rscratch1 = compilation.registerConfig.getScratchRegister();
@@ -103,9 +98,9 @@
@Override
protected void emitHere(CiValue dst, LIRDebugInfo info, boolean infoOnly) {
- masm.recordSafepoint(codePos(), info);
+ tasm.recordSafepoint(codePos(), info);
if (!infoOnly) {
- masm.codeBuffer.mark();
+ masm.codeBuffer.putMark();
masm.leaq(dst.asRegister(), new CiAddress(CiKind.Word, InstructionRelative.asValue(), 0));
}
}
@@ -163,10 +158,10 @@
if (constant.isNull()) {
masm.movq(dst, 0x0L);
} else if (target.inlineObjects) {
- masm.recordDataReferenceInCode(constant);
+ tasm.recordDataReferenceInCode(constant);
masm.movq(dst, 0xDEADDEADDEADDEADL);
} else {
- masm.movq(dst, masm.recordDataReferenceInCode(constant));
+ masm.movq(dst, tasm.recordDataReferenceInCode(constant));
}
}
@@ -181,7 +176,7 @@
if (constant == 0.0f) {
masm.xorps(dst, dst);
} else {
- masm.movflt(dst, masm.recordDataReferenceInCode(CiConstant.forFloat(constant)));
+ masm.movflt(dst, tasm.recordDataReferenceInCode(CiConstant.forFloat(constant)));
}
}
@@ -189,7 +184,7 @@
if (constant == 0.0f) {
masm.xorpd(dst, dst);
} else {
- masm.movdbl(dst, masm.recordDataReferenceInCode(CiConstant.forDouble(constant)));
+ masm.movdbl(dst, tasm.recordDataReferenceInCode(CiConstant.forDouble(constant)));
}
}
@@ -199,6 +194,7 @@
assert dest.isRegister();
CiConstant c = (CiConstant) src;
+ // Checkstyle: off
switch (c.kind) {
case Boolean :
case Byte :
@@ -213,6 +209,7 @@
case Double : const2reg(asXmmDoubleReg(dest), c.asDouble()); break;
default : throw Util.shouldNotReachHere();
}
+ // Checkstyle: on
}
@Override
@@ -222,6 +219,7 @@
CiStackSlot slot = (CiStackSlot) dst;
CiConstant c = (CiConstant) src;
+ // Checkstyle: off
switch (c.kind) {
case Boolean :
case Byte :
@@ -230,11 +228,12 @@
case Jsr :
case Int : masm.movl(frameMap.toStackAddress(slot), c.asInt()); break;
case Float : masm.movl(frameMap.toStackAddress(slot), floatToRawIntBits(c.asFloat())); break;
- case Object : masm.movoop(frameMap.toStackAddress(slot), c); break;
+ case Object : movoop(frameMap.toStackAddress(slot), c); break;
case Long : masm.mov64(frameMap.toStackAddress(slot), c.asLong()); break;
case Double : masm.mov64(frameMap.toStackAddress(slot), doubleToRawLongBits(c.asDouble())); break;
default : throw Util.shouldNotReachHere("Unknown constant kind for const2stack: " + c.kind);
}
+ // Checkstyle: on
}
@Override
@@ -245,6 +244,7 @@
CiAddress addr = asAddress(dst);
int nullCheckHere = codePos();
+ // Checkstyle: off
switch (kind) {
case Boolean :
case Byte : masm.movb(addr, constant.asInt() & 0xFF); break;
@@ -253,7 +253,7 @@
case Jsr :
case Int : masm.movl(addr, constant.asInt()); break;
case Float : masm.movl(addr, floatToRawIntBits(constant.asFloat())); break;
- case Object : masm.movoop(addr, constant); break;
+ case Object : movoop(addr, constant); break;
case Word:
case Long : masm.movq(rscratch1, constant.asLong());
nullCheckHere = codePos();
@@ -263,9 +263,10 @@
masm.movq(addr, rscratch1); break;
default : throw Util.shouldNotReachHere();
}
+ // Checkstyle: on
if (info != null) {
- asm.recordImplicitException(nullCheckHere, info);
+ tasm.recordImplicitException(nullCheckHere, info);
}
}
@@ -287,8 +288,9 @@
protected void reg2stack(CiValue src, CiValue dst, CiKind kind) {
assert src.isRegister();
assert dst.isStackSlot();
- CiAddress addr = frameMap.toStackAddress(((CiStackSlot) dst));
+ CiAddress addr = frameMap.toStackAddress((CiStackSlot) dst);
+ // Checkstyle: off
switch (src.kind) {
case Boolean :
case Byte :
@@ -303,6 +305,7 @@
case Double : masm.movsd(addr, asXmmDoubleReg(src)); break;
default : throw Util.shouldNotReachHere();
}
+ // Checkstyle: on
}
@Override
@@ -310,9 +313,10 @@
CiAddress toAddr = (CiAddress) dest;
if (info != null) {
- asm.recordImplicitException(codePos(), info);
+ tasm.recordImplicitException(codePos(), info);
}
+ // Checkstyle: off
switch (kind) {
case Float : masm.movflt(toAddr, asXmmFloatReg(src)); break;
case Double : masm.movsd(toAddr, asXmmDoubleReg(src)); break;
@@ -327,6 +331,7 @@
case Boolean : masm.movb(toAddr, src.asRegister()); break;
default : throw Util.shouldNotReachHere();
}
+ // Checkstyle: on
}
private static CiRegister asXmmFloatReg(CiValue src) {
@@ -341,8 +346,9 @@
assert src.isStackSlot();
assert dest.isRegister();
- CiAddress addr = frameMap.toStackAddress(((CiStackSlot) src));
+ CiAddress addr = frameMap.toStackAddress((CiStackSlot) src);
+ // Checkstyle: off
switch (dest.kind) {
case Boolean :
case Byte :
@@ -357,38 +363,39 @@
case Double : masm.movdbl(asXmmDoubleReg(dest), addr); break;
default : throw Util.shouldNotReachHere();
}
+ // Checkstyle: on
}
@Override
protected void mem2mem(CiValue src, CiValue dest, CiKind kind) {
if (dest.kind.isInt()) {
- masm.pushl(((CiAddress) src));
- masm.popl(((CiAddress) dest));
+ masm.pushl((CiAddress) src);
+ masm.popl((CiAddress) dest);
} else {
- masm.pushptr(((CiAddress) src));
- masm.popptr(((CiAddress) dest));
+ masm.pushptr((CiAddress) src);
+ masm.popptr((CiAddress) dest);
}
}
@Override
protected void mem2stack(CiValue src, CiValue dest, CiKind kind) {
if (dest.kind.isInt()) {
- masm.pushl(((CiAddress) src));
- masm.popl(frameMap.toStackAddress(((CiStackSlot) dest)));
+ masm.pushl((CiAddress) src);
+ masm.popl(frameMap.toStackAddress((CiStackSlot) dest));
} else {
- masm.pushptr(((CiAddress) src));
- masm.popptr(frameMap.toStackAddress(((CiStackSlot) dest)));
+ masm.pushptr((CiAddress) src);
+ masm.popptr(frameMap.toStackAddress((CiStackSlot) dest));
}
}
@Override
protected void stack2stack(CiValue src, CiValue dest, CiKind kind) {
if (src.kind.isInt()) {
- masm.pushl(frameMap.toStackAddress(((CiStackSlot) src)));
- masm.popl(frameMap.toStackAddress(((CiStackSlot) dest)));
+ masm.pushl(frameMap.toStackAddress((CiStackSlot) src));
+ masm.popl(frameMap.toStackAddress((CiStackSlot) dest));
} else {
- masm.pushptr(frameMap.toStackAddress(((CiStackSlot) src)));
- masm.popptr(frameMap.toStackAddress(((CiStackSlot) dest)));
+ masm.pushptr(frameMap.toStackAddress((CiStackSlot) src));
+ masm.popptr(frameMap.toStackAddress((CiStackSlot) dest));
}
}
@@ -399,9 +406,10 @@
CiAddress addr = (CiAddress) src;
if (info != null) {
- asm.recordImplicitException(codePos(), info);
+ tasm.recordImplicitException(codePos(), info);
}
+ // Checkstyle: off
switch (kind) {
case Float : masm.movflt(asXmmFloatReg(dest), addr); break;
case Double : masm.movdbl(asXmmDoubleReg(dest), addr); break;
@@ -415,21 +423,25 @@
case Short : masm.movswl(dest.asRegister(), addr); break;
default : throw Util.shouldNotReachHere();
}
+ // Checkstyle: on
}
@Override
protected void emitReadPrefetch(CiValue src) {
CiAddress addr = (CiAddress) src;
+ // Checkstyle: off
switch (C1XOptions.ReadPrefetchInstr) {
case 0 : masm.prefetchnta(addr); break;
case 1 : masm.prefetcht0(addr); break;
case 2 : masm.prefetcht2(addr); break;
default : throw Util.shouldNotReachHere();
}
+ // Checkstyle: on
}
@Override
protected void emitOp3(LIROp3 op) {
+ // Checkstyle: off
switch (op.code) {
case Idiv :
case Irem : arithmeticIdiv(op.code, op.opr1(), op.opr2(), op.result(), op.info); break;
@@ -441,6 +453,7 @@
case Wremi : arithmeticWdiv(op.code, op.opr1(), op.opr2(), op.result(), op.info); break;
default : throw Util.shouldNotReachHere();
}
+ // Checkstyle: on
}
private boolean assertEmitBranch(LIRBranch op) {
@@ -487,7 +500,7 @@
// Set scratch to address of jump table
int leaPos = buf.position();
- buf.mark();
+ buf.putMark();
masm.leaq(rscratch1, new CiAddress(CiKind.Word, InstructionRelative.asValue(), 0));
// Load jump table entry into scratch and jump to it
@@ -503,7 +516,7 @@
// Patch LEA instruction above now that we know the position of the jump table
int jumpTablePos = buf.position();
buf.setPosition(leaPos);
- buf.mark();
+ buf.putMark();
masm.leaq(rscratch1, new CiAddress(CiKind.Word, InstructionRelative.asValue(), jumpTablePos - leaPos));
buf.setPosition(jumpTablePos);
@@ -524,7 +537,7 @@
}
JumpTable jt = new JumpTable(jumpTablePos, op.lowKey, highKey, 4);
- masm.targetMethod.addAnnotation(jt);
+ tasm.targetMethod.addAnnotation(jt);
}
@Override
@@ -535,8 +548,8 @@
if (op.cond() == Condition.TRUE) {
if (op.info != null) {
int codePos = codePos();
- if (codePos > asm.lastSafepointPos()) {
- asm.recordImplicitException(codePos, op.info);
+ if (codePos > tasm.lastSafepointPos()) {
+ tasm.recordImplicitException(codePos, op.info);
}
}
masm.jmp(op.label());
@@ -545,6 +558,7 @@
if (op.code == LIROpcode.CondFloatBranch) {
assert op.unorderedBlock() != null : "must have unordered successor";
masm.jcc(ConditionFlag.parity, op.unorderedBlock().label());
+ // Checkstyle: off
switch (op.cond()) {
case EQ : acond = ConditionFlag.equal; break;
case NE : acond = ConditionFlag.notEqual; break;
@@ -566,8 +580,9 @@
case AE : acond = ConditionFlag.aboveEqual; break;
default : throw Util.shouldNotReachHere();
}
+ // Checkstyle: on
}
- masm.jcc(acond, (op.label()));
+ masm.jcc(acond, op.label());
}
}
@@ -622,7 +637,7 @@
masm.cvttss2sil(dest.asRegister(), srcRegister);
masm.cmp32(dest.asRegister(), Integer.MIN_VALUE);
masm.jcc(ConditionFlag.notEqual, endLabel);
- masm.callGlobalStub(op.globalStub, null, dest.asRegister(), src);
+ callGlobalStub(op.globalStub, null, dest.asRegister(), src);
// cannot cause an exception
masm.bind(endLabel);
break;
@@ -632,7 +647,7 @@
masm.cvttsd2sil(dest.asRegister(), asXmmDoubleReg(src));
masm.cmp32(dest.asRegister(), Integer.MIN_VALUE);
masm.jcc(ConditionFlag.notEqual, endLabel);
- masm.callGlobalStub(op.globalStub, null, dest.asRegister(), src);
+ callGlobalStub(op.globalStub, null, dest.asRegister(), src);
// cannot cause an exception
masm.bind(endLabel);
break;
@@ -651,7 +666,7 @@
masm.movq(rscratch1, java.lang.Long.MIN_VALUE);
masm.cmpq(dest.asRegister(), rscratch1);
masm.jcc(ConditionFlag.notEqual, endLabel);
- masm.callGlobalStub(op.globalStub, null, dest.asRegister(), src);
+ callGlobalStub(op.globalStub, null, dest.asRegister(), src);
masm.bind(endLabel);
break;
}
@@ -662,7 +677,7 @@
masm.movq(rscratch1, java.lang.Long.MIN_VALUE);
masm.cmpq(dest.asRegister(), rscratch1);
masm.jcc(ConditionFlag.notEqual, endLabel);
- masm.callGlobalStub(op.globalStub, null, dest.asRegister(), src);
+ callGlobalStub(op.globalStub, null, dest.asRegister(), src);
masm.bind(endLabel);
break;
}
@@ -824,6 +839,7 @@
assert left.equals(dest) : "left and dest must be equal";
CiKind kind = left.kind;
+ // Checkstyle: off
if (left.isRegister()) {
CiRegister lreg = left.asRegister();
@@ -891,7 +907,7 @@
raddr = frameMap.toStackAddress(((CiStackSlot) right));
} else {
assert right.isConstant();
- raddr = masm.recordDataReferenceInCode(CiConstant.forFloat(((CiConstant) right).asFloat()));
+ raddr = tasm.recordDataReferenceInCode(CiConstant.forFloat(((CiConstant) right).asFloat()));
}
switch (code) {
case Add : masm.addss(lreg, raddr); break;
@@ -907,7 +923,7 @@
raddr = frameMap.toStackAddress(((CiStackSlot) right));
} else {
assert right.isConstant();
- raddr = masm.recordDataReferenceInCode(CiConstant.forDouble(((CiConstant) right).asDouble()));
+ raddr = tasm.recordDataReferenceInCode(CiConstant.forDouble(((CiConstant) right).asDouble()));
}
switch (code) {
case Add : masm.addsd(lreg, raddr); break;
@@ -930,7 +946,7 @@
// register - constant
assert right.isConstant();
long c = ((CiConstant) right).asLong();
- if (Util.isInt(c)) {
+ if (NumUtil.isInt(c)) {
switch (code) {
case Add : masm.addq(lreg, (int) c); break;
case Sub : masm.subq(lreg, (int) c); break;
@@ -968,6 +984,7 @@
}
}
}
+ // Checkstyle: on
}
@Override
@@ -978,7 +995,7 @@
if (asXmmDoubleReg(dest) != asXmmDoubleReg(value)) {
masm.movdbl(asXmmDoubleReg(dest), asXmmDoubleReg(value));
}
- masm.andpd(asXmmDoubleReg(dest), masm.recordDataReferenceInCode(CiConstant.forLong(DoubleSignMask)));
+ masm.andpd(asXmmDoubleReg(dest), tasm.recordDataReferenceInCode(CiConstant.forLong(DoubleSignMask)));
break;
case Sqrt:
@@ -993,6 +1010,7 @@
@Override
protected void emitLogicOp(LIROpcode code, CiValue left, CiValue right, CiValue dst) {
assert left.isRegister();
+ // Checkstyle: off
if (left.kind.isInt()) {
CiRegister reg = left.asRegister();
if (right.isConstant()) {
@@ -1047,6 +1065,7 @@
CiRegister dreg = dst.asRegister();
moveRegs(lreg, dreg);
}
+ // Checkstyle: on
}
void arithmeticIdiv(LIROpcode code, CiValue left, CiValue right, CiValue result, LIRDebugInfo info) {
@@ -1113,7 +1132,7 @@
// normal and special case exit
masm.bind(continuation);
- asm.recordImplicitException(offset, info);
+ tasm.recordImplicitException(offset, info);
if (code == LIROpcode.Irem) {
moveRegs(AMD64.rdx, dreg); // result is in rdx
} else {
@@ -1162,7 +1181,7 @@
// normal and special case exit
masm.bind(continuation);
- asm.recordImplicitException(offset, info);
+ tasm.recordImplicitException(offset, info);
if (code == LIROpcode.Lrem) {
moveRegs(AMD64.rdx, dreg);
} else {
@@ -1195,7 +1214,7 @@
int offset = masm.codeBuffer.position();
masm.divq(rreg);
- asm.recordImplicitException(offset, info);
+ tasm.recordImplicitException(offset, info);
if (code == LIROpcode.Wrem || code == LIROpcode.Wremi) {
moveRegs(AMD64.rdx, dreg);
} else {
@@ -1206,6 +1225,7 @@
@Override
protected void emitCompare(Condition condition, CiValue opr1, CiValue opr2, LIROp2 op) {
+ // Checkstyle: off
assert Util.archKindsEqual(opr1.kind.stackKind(), opr2.kind.stackKind()) || (opr1.kind == CiKind.Word && opr2.kind == CiKind.Int) : "nonmatching stack kinds (" + condition + "): " + opr1.kind.stackKind() + "==" + opr2.kind.stackKind();
if (opr1.isConstant()) {
@@ -1257,8 +1277,8 @@
case Char :
case Short :
case Int : masm.cmpl(reg1, c.asInt()); break;
- case Float : masm.ucomiss(reg1, masm.recordDataReferenceInCode(CiConstant.forFloat(((CiConstant) opr2).asFloat()))); break;
- case Double : masm.ucomisd(reg1, masm.recordDataReferenceInCode(CiConstant.forDouble(((CiConstant) opr2).asDouble()))); break;
+ case Float : masm.ucomiss(reg1, tasm.recordDataReferenceInCode(CiConstant.forFloat(((CiConstant) opr2).asFloat()))); break;
+ case Double : masm.ucomisd(reg1, tasm.recordDataReferenceInCode(CiConstant.forDouble(((CiConstant) opr2).asDouble()))); break;
case Long :
case Word : {
if (c.asLong() == 0) {
@@ -1271,7 +1291,7 @@
break;
}
case Object : {
- masm.movoop(rscratch1, c);
+ movoop(rscratch1, c);
masm.cmpq(reg1, rscratch1);
break;
}
@@ -1292,7 +1312,7 @@
case Short :
case Int : masm.cmpl(left, right.asInt()); break;
case Long :
- case Word : assert Util.isInt(right.asLong());
+ case Word : assert NumUtil.isInt(right.asLong());
masm.cmpq(left, right.asInt()); break;
case Object : assert right.isNull();
masm.cmpq(left, 0); break;
@@ -1305,6 +1325,7 @@
} else {
throw Util.shouldNotReachHere(opr1.toString() + " opr2 = " + opr2);
}
+ // Checkstyle: on
}
@Override
@@ -1359,12 +1380,12 @@
} else {
moveOp(callAddress, reg.asValue(callAddress.kind), callAddress.kind, null, false);
}
- masm.indirectCall(reg, target, info);
+ indirectCall(reg, target, info);
}
@Override
protected void emitDirectCall(Object target, LIRDebugInfo info) {
- masm.directCall(target, info);
+ directCall(target, info);
}
@Override
@@ -1375,13 +1396,13 @@
} else {
moveOp(callAddress, reg.asValue(callAddress.kind), callAddress.kind, null, false);
}
- masm.nativeCall(reg, symbol, info);
+ indirectCall(reg, symbol, info);
}
@Override
protected void emitTemplateCall(CiValue address) {
if (address == null) {
- masm.directCall(null, null);
+ directCall(null, null);
return;
}
@@ -1391,7 +1412,7 @@
} else {
moveOp(address, reg.asValue(address.kind), address.kind, null, false);
}
- masm.indirectCall(reg, null, null);
+ indirectCall(reg, null, null);
}
@Override
@@ -1399,9 +1420,9 @@
// exception object is not added to oop map by LinearScan
// (LinearScan assumes that no oops are in fixed registers)
// info.addRegisterOop(exceptionOop);
- masm.directCall(CiRuntimeCall.HandleException, info);
+ directCall(CiRuntimeCall.HandleException, info);
// enough room for two byte trap
- masm.shouldNotReachHere();
+ shouldNotReachHere();
}
private void emitXIRShiftOp(LIROpcode code, CiValue left, CiValue count, CiValue dest) {
@@ -1427,6 +1448,7 @@
CiRegister value = left.asRegister();
assert value != SHIFTCount : "left cannot be ECX";
+ // Checkstyle: off
switch (code) {
case Shl : masm.shll(value); break;
case Shr : masm.sarl(value); break;
@@ -1443,6 +1465,7 @@
case Ushr : masm.shrq(lreg); break;
default : throw Util.shouldNotReachHere();
}
+ // Checkstyle: on
}
}
@@ -1455,6 +1478,7 @@
count = count & 0x1F; // Java spec
moveRegs(left.asRegister(), value);
+ // Checkstyle: off
switch (code) {
case Shl : masm.shll(value, count); break;
case Shr : masm.sarl(value, count); break;
@@ -1474,6 +1498,7 @@
case Ushr : masm.shrq(value, count); break;
default : throw Util.shouldNotReachHere();
}
+ // Checkstyle: on
}
}
@@ -1519,14 +1544,14 @@
if (asXmmFloatReg(left) != asXmmFloatReg(dest)) {
masm.movflt(asXmmFloatReg(dest), asXmmFloatReg(left));
}
- masm.callGlobalStub(op.globalStub, null, asXmmFloatReg(dest), dest);
+ callGlobalStub(op.globalStub, null, asXmmFloatReg(dest), dest);
} else if (dest.kind.isDouble()) {
if (asXmmDoubleReg(left) != asXmmDoubleReg(dest)) {
masm.movdbl(asXmmDoubleReg(dest), asXmmDoubleReg(left));
}
- masm.callGlobalStub(op.globalStub, null, asXmmDoubleReg(dest), dest);
+ callGlobalStub(op.globalStub, null, asXmmDoubleReg(dest), dest);
} else {
CiRegister lreg = left.asRegister();
CiRegister dreg = dest.asRegister();
@@ -1542,29 +1567,39 @@
}
@Override
+ protected void emitNullCheck(CiValue src, LIRDebugInfo info) {
+ assert src.isRegister();
+ if (C1XOptions.NullCheckUniquePc) {
+ masm.nop();
+ }
+ tasm.recordImplicitException(codePos(), info);
+ masm.nullCheck(src.asRegister());
+ }
+
+ @Override
protected void emitVolatileMove(CiValue src, CiValue dest, CiKind kind, LIRDebugInfo info) {
assert kind == CiKind.Long : "only for volatile long fields";
if (info != null) {
- asm.recordImplicitException(codePos(), info);
+ tasm.recordImplicitException(codePos(), info);
}
if (src.kind.isDouble()) {
if (dest.isRegister()) {
masm.movdq(dest.asRegister(), asXmmDoubleReg(src));
} else if (dest.isStackSlot()) {
- masm.movsd(frameMap.toStackAddress(((CiStackSlot) dest)), asXmmDoubleReg(src));
+ masm.movsd(frameMap.toStackAddress((CiStackSlot) dest), asXmmDoubleReg(src));
} else {
assert dest.isAddress();
- masm.movsd(((CiAddress) dest), asXmmDoubleReg(src));
+ masm.movsd((CiAddress) dest, asXmmDoubleReg(src));
}
} else {
assert dest.kind.isDouble();
if (src.isStackSlot()) {
- masm.movdbl(asXmmDoubleReg(dest), frameMap.toStackAddress(((CiStackSlot) src)));
+ masm.movdbl(asXmmDoubleReg(dest), frameMap.toStackAddress((CiStackSlot) src));
} else {
assert src.isAddress();
- masm.movdbl(asXmmDoubleReg(dest), ((CiAddress) src));
+ masm.movdbl(asXmmDoubleReg(dest), (CiAddress) src);
}
}
}
@@ -1681,7 +1716,7 @@
case PointerLoad: {
if ((Boolean) inst.extra && info != null) {
- asm.recordImplicitException(codePos(), info);
+ tasm.recordImplicitException(codePos(), info);
}
CiValue result = operands[inst.result.index];
@@ -1693,7 +1728,7 @@
case PointerStore: {
if ((Boolean) inst.extra && info != null) {
- asm.recordImplicitException(codePos(), info);
+ tasm.recordImplicitException(codePos(), info);
}
CiValue value = operands[inst.y().index];
@@ -1726,7 +1761,7 @@
src = new CiAddress(inst.kind, pointer, index, scale, displacement);
}
- moveOp(src, result, inst.kind, (canTrap) ? info : null, false);
+ moveOp(src, result, inst.kind, canTrap ? info : null, false);
break;
}
@@ -1770,7 +1805,7 @@
dst = new CiAddress(inst.kind, pointer, index, scale, displacement);
}
- moveOp(value, dst, inst.kind, (canTrap) ? info : null, false);
+ moveOp(value, dst, inst.kind, canTrap ? info : null, false);
break;
}
@@ -1791,7 +1826,7 @@
case PointerCAS:
if ((Boolean) inst.extra && info != null) {
- asm.recordImplicitException(codePos(), info);
+ tasm.recordImplicitException(codePos(), info);
}
assert operands[inst.x().index].asRegister().equals(AMD64.rax) : "wrong input x: " + operands[inst.x().index];
@@ -1813,7 +1848,7 @@
for (int i = 0; i < args.length; i++) {
args[i] = operands[inst.arguments[i].index];
}
- masm.callGlobalStub(stubId, info, result, args);
+ callGlobalStub(stubId, info, result, args);
break;
}
case CallRuntime: {
@@ -1832,7 +1867,7 @@
}
RuntimeCallInformation runtimeCallInformation = (RuntimeCallInformation) inst.extra;
- masm.directCall(runtimeCallInformation.target, (runtimeCallInformation.useInfoAfter) ? infoAfter : info);
+ directCall(runtimeCallInformation.target, (runtimeCallInformation.useInfoAfter) ? infoAfter : info);
if (inst.result != null && inst.result.kind != CiKind.Illegal && inst.result.kind != CiKind.Void) {
CiRegister returnRegister = compilation.registerConfig.getReturnRegister(inst.result.kind);
@@ -1846,7 +1881,7 @@
Label label = labels[((XirLabel) inst.extra).index];
masm.jmp(label);
} else {
- masm.directJmp(inst.extra);
+ directJmp(inst.extra);
}
break;
}
@@ -1925,17 +1960,17 @@
}
case Safepoint: {
assert info != null : "Must have debug info in order to create a safepoint.";
- asm.recordSafepoint(codePos(), info);
+ tasm.recordSafepoint(codePos(), info);
break;
}
case NullCheck: {
- asm.recordImplicitException(codePos(), info);
+ tasm.recordImplicitException(codePos(), info);
CiValue pointer = operands[inst.x().index];
- asm.nullCheck(pointer.asRegister());
+ masm.nullCheck(pointer.asRegister());
break;
}
case Align: {
- asm.align((Integer) inst.extra);
+ masm.align((Integer) inst.extra);
break;
}
case StackOverflowCheck: {
@@ -2002,7 +2037,7 @@
references[i] = marks.get(xmark.references[i]);
assert references[i] != null;
}
- Mark mark = asm.recordMark(xmark.id, references);
+ Mark mark = tasm.recordMark(xmark.id, references);
marks.put(xmark, mark);
break;
}
@@ -2014,15 +2049,15 @@
}
case RawBytes: {
for (byte b : (byte[]) inst.extra) {
- masm.emitByte(b & 0xff);
+ masm.codeBuffer.emitByte(b & 0xff);
}
break;
}
case ShouldNotReachHere: {
if (inst.extra == null) {
- masm.stop("should not reach here");
+ stop("should not reach here");
} else {
- masm.stop("should not reach here: " + inst.extra);
+ stop("should not reach here: " + inst.extra);
}
break;
}
@@ -2039,7 +2074,7 @@
* a slot "up" the stack above RSP).
*/
private void bangStackWithOffset(int offset) {
- masm.movq(new CiAddress(CiKind.Word, AMD64.RSP, (-offset)), AMD64.rax);
+ masm.movq(new CiAddress(CiKind.Word, AMD64.RSP, -offset), AMD64.rax);
}
private CiRegisterValue assureInRegister(CiValue pointer) {
@@ -2063,7 +2098,128 @@
@Override
public void emitDeoptizationStub(DeoptimizationStub stub) {
masm.bind(stub.label);
- masm.directCall(CiRuntimeCall.Deoptimize, stub.info);
- masm.shouldNotReachHere();
+ directCall(CiRuntimeCall.Deoptimize, stub.info);
+ shouldNotReachHere();
+ }
+
+ public GlobalStub lookupGlobalStub(XirTemplate template) {
+ return compilation.compiler.lookupGlobalStub(template);
+ }
+
+ public void callGlobalStub(XirTemplate stub, LIRDebugInfo info, CiRegister result, CiValue... args) {
+ callGlobalStubHelper(lookupGlobalStub(stub), stub.resultOperand.kind, info, result, args);
+ }
+
+ public void callGlobalStub(GlobalStub stub, LIRDebugInfo info, CiRegister result, CiValue... args) {
+ callGlobalStubHelper(stub, stub.resultKind, info, result, args);
+ }
+
+ private void callGlobalStubHelper(GlobalStub stub, CiKind resultKind, LIRDebugInfo info, CiRegister result, CiValue... args) {
+ assert args.length == stub.argOffsets.length;
+
+ for (int i = 0; i < args.length; i++) {
+ storeParameter(args[i], stub.argOffsets[i]);
+ }
+
+ directCall(stub.stubObject, info);
+
+ if (result != CiRegister.None) {
+ loadResult(result, stub.resultOffset, resultKind);
+ }
+
+ // Clear out parameters
+ if (C1XOptions.GenAssertionCode) {
+ for (int i = 0; i < args.length; i++) {
+ masm.movptr(new CiAddress(CiKind.Word, AMD64.RSP, stub.argOffsets[i]), 0);
+ }
+ }
+ }
+
+ private void loadResult(CiRegister r, int offset, CiKind kind) {
+ if (kind == CiKind.Int || kind == CiKind.Boolean) {
+ masm.movl(r, new CiAddress(CiKind.Int, AMD64.RSP, offset));
+ } else if (kind == CiKind.Float) {
+ masm.movss(r, new CiAddress(CiKind.Float, AMD64.RSP, offset));
+ } else if (kind == CiKind.Double) {
+ masm.movsd(r, new CiAddress(CiKind.Double, AMD64.RSP, offset));
+ } else {
+ masm.movq(r, new CiAddress(CiKind.Word, AMD64.RSP, offset));
+ }
+ }
+
+ private void storeParameter(CiValue registerOrConstant, int offset) {
+ CiKind k = registerOrConstant.kind;
+ if (registerOrConstant.isConstant()) {
+ CiConstant c = (CiConstant) registerOrConstant;
+ if (c.kind == CiKind.Object) {
+ movoop(new CiAddress(CiKind.Word, AMD64.RSP, offset), c);
+ } else {
+ masm.movptr(new CiAddress(CiKind.Word, AMD64.RSP, offset), c.asInt());
+ }
+ } else if (registerOrConstant.isRegister()) {
+ if (k.isFloat()) {
+ masm.movss(new CiAddress(CiKind.Float, AMD64.RSP, offset), registerOrConstant.asRegister());
+ } else if (k.isDouble()) {
+ masm.movsd(new CiAddress(CiKind.Double, AMD64.RSP, offset), registerOrConstant.asRegister());
+ } else {
+ masm.movq(new CiAddress(CiKind.Word, AMD64.RSP, offset), registerOrConstant.asRegister());
+ }
+ } else {
+ throw new InternalError("should not reach here");
+ }
+ }
+
+ public void movoop(CiRegister dst, CiConstant obj) {
+ assert obj.kind == CiKind.Object;
+ if (obj.isNull()) {
+ masm.xorq(dst, dst);
+ } else {
+ if (target.inlineObjects) {
+ tasm.recordDataReferenceInCode(obj);
+ masm.movq(dst, 0xDEADDEADDEADDEADL);
+ } else {
+ masm.movq(dst, tasm.recordDataReferenceInCode(obj));
+ }
+ }
+ }
+
+ public void movoop(CiAddress dst, CiConstant obj) {
+ movoop(rscratch1, obj);
+ masm.movq(dst, rscratch1);
+ }
+
+ public void directCall(Object target, LIRDebugInfo info) {
+ int before = masm.codeBuffer.position();
+ masm.call();
+ int after = masm.codeBuffer.position();
+ tasm.recordDirectCall(before, after, target, info);
+ tasm.recordExceptionHandlers(after, info);
+ }
+
+ public void directJmp(Object target) {
+ int before = masm.codeBuffer.position();
+ masm.jmp(0, true);
+ int after = masm.codeBuffer.position();
+ tasm.recordDirectCall(before, after, target, null);
+ }
+
+ public void indirectCall(CiRegister dst, Object target, LIRDebugInfo info) {
+ int before = masm.codeBuffer.position();
+ masm.call(dst);
+ int after = masm.codeBuffer.position();
+ tasm.recordIndirectCall(before, after, target, info);
+ tasm.recordExceptionHandlers(after, info);
+ }
+
+ protected void stop(String msg) {
+ if (C1XOptions.GenAssertionCode) {
+ // TODO: pass a pointer to the message
+ directCall(CiRuntimeCall.Debug, null);
+ masm.hlt();
+ }
+ }
+
+ public void shouldNotReachHere() {
+ stop("should not reach here");
}
}
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java
--- a/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java Fri May 13 17:09:20 2011 -0700
@@ -23,6 +23,8 @@
package com.sun.c1x.target.amd64;
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
import com.sun.c1x.*;
import com.sun.c1x.gen.*;
import com.sun.c1x.globalstub.*;
@@ -34,9 +36,6 @@
/**
* This class implements the X86-specific portion of the LIR generator.
- *
- * @author Thomas Wuerthinger
- * @author Ben L. Titzer
*/
public class AMD64LIRGenerator extends LIRGenerator {
@@ -74,7 +73,7 @@
@Override
protected boolean canInlineAsConstant(Value v) {
if (v.kind == CiKind.Long) {
- if (v.isConstant() && Util.isInt(v.asConstant().asLong())) {
+ if (v.isConstant() && NumUtil.isInt(v.asConstant().asLong())) {
return true;
}
return false;
@@ -150,7 +149,7 @@
LIRItem left = new LIRItem(x.x(), this);
LIRItem right = new LIRItem(x.y(), this);
assert !left.isStack() || !right.isStack() : "can't both be memory operands";
- boolean mustLoadBoth = (x.opcode == Bytecodes.FREM || x.opcode == Bytecodes.DREM);
+ boolean mustLoadBoth = x.opcode == Bytecodes.FREM || x.opcode == Bytecodes.DREM;
// Both are in register, swap operands such that the short-living one is on the left side.
if (x.isCommutative() && left.isRegisterOrVariable() && right.isRegisterOrVariable()) {
@@ -433,7 +432,7 @@
} else if (x.x().kind.isFloat() || x.x().kind.isDouble()) {
CiValue reg = createResultVariable(x);
int code = x.opcode;
- lir.fcmp2int(left.result(), right.result(), reg, (code == Bytecodes.FCMPL || code == Bytecodes.DCMPL));
+ lir.fcmp2int(left.result(), right.result(), reg, code == Bytecodes.FCMPL || code == Bytecodes.DCMPL);
} else if (x.x().kind.isLong() || x.x().kind.isWord()) {
CiValue reg = createResultVariable(x);
lir.lcmp2int(left.result(), right.result(), reg);
@@ -448,12 +447,14 @@
CiVariable result = newVariable(x.kind);
// arguments of lirConvert
GlobalStub globalStub = null;
+ // Checkstyle: off
switch (x.opcode) {
case Bytecodes.F2I: globalStub = stubFor(GlobalStub.Id.f2i); break;
case Bytecodes.F2L: globalStub = stubFor(GlobalStub.Id.f2l); break;
case Bytecodes.D2I: globalStub = stubFor(GlobalStub.Id.d2i); break;
case Bytecodes.D2L: globalStub = stubFor(GlobalStub.Id.d2l); break;
}
+ // Checkstyle: on
if (globalStub != null) {
// Force result to be rax to match global stubs expectation.
CiValue stubResult = x.kind == CiKind.Int ? RAX_I : RAX_L;
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64MacroAssembler.java
--- a/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64MacroAssembler.java Fri May 13 14:03:03 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,506 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.c1x.target.amd64;
-
-import com.sun.c1x.*;
-import com.sun.c1x.asm.*;
-import com.sun.c1x.globalstub.*;
-import com.sun.c1x.lir.*;
-import com.sun.c1x.util.*;
-import com.sun.cri.ci.*;
-import com.sun.cri.ri.*;
-import com.sun.cri.xir.*;
-
-/**
- * This class implements the AMD64-specific portion of the macro assembler.
- *
- * @author Thomas Wuerthinger
- * @author Ben L. Titzer
- */
-public class AMD64MacroAssembler extends AMD64Assembler {
-
- private final CiRegister rscratch1;
-
- public static class WithCompiler extends AMD64MacroAssembler {
-
- private final C1XCompiler compiler;
-
- public WithCompiler(C1XCompiler compiler, RiRegisterConfig registerConfig) {
- super(compiler.target, registerConfig);
- this.compiler = compiler;
- }
-
- @Override
- public GlobalStub lookupGlobalStub(XirTemplate template) {
- return compiler.lookupGlobalStub(template);
- }
- }
-
- public AMD64MacroAssembler(CiTarget target, RiRegisterConfig registerConfig) {
- super(target, registerConfig);
- this.rscratch1 = registerConfig.getScratchRegister();
- }
-
- /**
- * Must be overridden if compiling code that makes calls to global stubs.
- */
- public GlobalStub lookupGlobalStub(XirTemplate template) {
- throw new IllegalArgumentException("This assembler does not support compiling calls to global stubs");
- }
-
- public final int callGlobalStub(XirTemplate stub, LIRDebugInfo info, CiRegister result, CiValue... args) {
- assert args.length == stub.parameters.length;
- return callGlobalStubHelper(lookupGlobalStub(stub), stub.resultOperand.kind, info, result, args);
- }
-
- public final int callGlobalStub(GlobalStub stub, LIRDebugInfo info, CiRegister result, CiValue... args) {
- assert args.length == stub.argOffsets.length;
- return callGlobalStubHelper(stub, stub.resultKind, info, result, args);
- }
-
- private int callGlobalStubHelper(GlobalStub stub, CiKind resultKind, LIRDebugInfo info, CiRegister result, CiValue... args) {
- for (int i = 0; i < args.length; i++) {
- storeParameter(args[i], stub.argOffsets[i]);
- }
-
- int pos = directCall(stub.stubObject, info);
-
- if (result != CiRegister.None) {
- loadResult(result, stub.resultOffset, resultKind);
- }
-
- // Clear out parameters
- if (C1XOptions.GenAssertionCode) {
- for (int i = 0; i < args.length; i++) {
- movptr(new CiAddress(CiKind.Word, AMD64.RSP, stub.argOffsets[i]), 0);
- }
- }
- return pos;
- }
-
- private void loadResult(CiRegister r, int offset, CiKind kind) {
- if (kind == CiKind.Int || kind == CiKind.Boolean) {
- movl(r, new CiAddress(CiKind.Int, AMD64.RSP, offset));
- } else if (kind == CiKind.Float) {
- movss(r, new CiAddress(CiKind.Float, AMD64.RSP, offset));
- } else if (kind == CiKind.Double) {
- movsd(r, new CiAddress(CiKind.Double, AMD64.RSP, offset));
- } else {
- movq(r, new CiAddress(CiKind.Word, AMD64.RSP, offset));
- }
- }
-
- private void storeParameter(CiValue registerOrConstant, int offset) {
- CiKind k = registerOrConstant.kind;
- if (registerOrConstant.isConstant()) {
- CiConstant c = (CiConstant) registerOrConstant;
- if (c.kind == CiKind.Object) {
- movoop(new CiAddress(CiKind.Word, AMD64.RSP, offset), c);
- } else {
- movptr(new CiAddress(CiKind.Word, AMD64.RSP, offset), c.asInt());
- }
- } else if (registerOrConstant.isRegister()) {
- if (k.isFloat()) {
- movss(new CiAddress(CiKind.Float, AMD64.RSP, offset), registerOrConstant.asRegister());
- } else if (k.isDouble()) {
- movsd(new CiAddress(CiKind.Double, AMD64.RSP, offset), registerOrConstant.asRegister());
- } else {
- movq(new CiAddress(CiKind.Word, AMD64.RSP, offset), registerOrConstant.asRegister());
- }
- } else {
- Util.shouldNotReachHere();
- }
- }
-
- void movoop(CiRegister dst, CiConstant obj) {
- assert obj.kind == CiKind.Object;
- if (obj.isNull()) {
- xorq(dst, dst);
- } else {
- if (target.inlineObjects) {
- recordDataReferenceInCode(obj);
- movq(dst, 0xDEADDEADDEADDEADL);
- } else {
- movq(dst, recordDataReferenceInCode(obj));
- }
- }
- }
-
- void movoop(CiAddress dst, CiConstant obj) {
- movoop(rscratch1, obj);
- movq(dst, rscratch1);
- }
-
- void mov64(CiAddress dst, long src) {
- movq(rscratch1, src);
- movq(dst, rscratch1);
- }
-
- void pushptr(CiAddress src) {
- pushq(src);
- }
-
- void popptr(CiAddress src) {
- popq(src);
- }
-
- void xorptr(CiRegister dst, CiRegister src) {
- xorq(dst, src);
- }
-
- void xorptr(CiRegister dst, CiAddress src) {
- xorq(dst, src);
- }
-
- // 64 bit versions
-
- int correctedIdivq(CiRegister reg) {
- // Full implementation of Java ldiv and lrem; checks for special
- // case as described in JVM spec. : p.243 & p.271. The function
- // returns the (pc) offset of the idivl instruction - may be needed
- // for implicit exceptions.
- //
- // normal case special case
- //
- // input : X86Register.rax: dividend minLong
- // reg: divisor (may not be eax/edx) -1
- //
- // output: X86Register.rax: quotient (= X86Register.rax idiv reg) minLong
- // X86Register.rdx: remainder (= X86Register.rax irem reg) 0
- assert reg != AMD64.rax && reg != AMD64.rdx : "reg cannot be X86Register.rax or X86Register.rdx register";
- final long minLong = 0x8000000000000000L;
- Label normalCase = new Label();
- Label specialCase = new Label();
-
- // check for special case
- cmpq(AMD64.rax, recordDataReferenceInCode(CiConstant.forLong(minLong)));
- jcc(AMD64Assembler.ConditionFlag.notEqual, normalCase);
- xorl(AMD64.rdx, AMD64.rdx); // prepare X86Register.rdx for possible special case (where
- // remainder = 0)
- cmpq(reg, -1);
- jcc(AMD64Assembler.ConditionFlag.equal, specialCase);
-
- // handle normal case
- bind(normalCase);
- cdqq();
- int idivqOffset = codeBuffer.position();
- idivq(reg);
-
- // normal and special case exit
- bind(specialCase);
-
- return idivqOffset;
- }
-
- void decrementq(CiRegister reg, int value) {
- if (value == Integer.MIN_VALUE) {
- subq(reg, value);
- return;
- }
- if (value < 0) {
- incrementq(reg, -value);
- return;
- }
- if (value == 0) {
- return;
- }
- if (value == 1 && C1XOptions.UseIncDec) {
- decq(reg);
- } else {
- subq(reg, value);
- }
- }
-
- void incrementq(CiRegister reg, int value) {
- if (value == Integer.MIN_VALUE) {
- addq(reg, value);
- return;
- }
- if (value < 0) {
- decrementq(reg, -value);
- return;
- }
- if (value == 0) {
- return;
- }
- if (value == 1 && C1XOptions.UseIncDec) {
- incq(reg);
- } else {
- addq(reg, value);
- }
- }
-
- // These are mostly for initializing null
- void movptr(CiAddress dst, int src) {
- movslq(dst, src);
- }
-
- void stop(String msg) {
- if (C1XOptions.GenAssertionCode) {
- // TODO: pass a pointer to the message
- directCall(CiRuntimeCall.Debug, null);
- hlt();
- }
- }
-
- public final void cmp32(CiRegister src1, int imm) {
- cmpl(src1, imm);
- }
-
- public final void cmp32(CiRegister src1, CiAddress src2) {
- cmpl(src1, src2);
- }
-
- void cmpsd2int(CiRegister opr1, CiRegister opr2, CiRegister dst, boolean unorderedIsLess) {
- assert opr1.isFpu() && opr2.isFpu();
- ucomisd(opr1, opr2);
-
- Label l = new Label();
- if (unorderedIsLess) {
- movl(dst, -1);
- jcc(AMD64Assembler.ConditionFlag.parity, l);
- jcc(AMD64Assembler.ConditionFlag.below, l);
- movl(dst, 0);
- jcc(AMD64Assembler.ConditionFlag.equal, l);
- incrementl(dst, 1);
- } else { // unordered is greater
- movl(dst, 1);
- jcc(AMD64Assembler.ConditionFlag.parity, l);
- jcc(AMD64Assembler.ConditionFlag.above, l);
- movl(dst, 0);
- jcc(AMD64Assembler.ConditionFlag.equal, l);
- decrementl(dst, 1);
- }
- bind(l);
- }
-
- void cmpss2int(CiRegister opr1, CiRegister opr2, CiRegister dst, boolean unorderedIsLess) {
- assert opr1.isFpu();
- assert opr2.isFpu();
- ucomiss(opr1, opr2);
-
- Label l = new Label();
- if (unorderedIsLess) {
- movl(dst, -1);
- jcc(AMD64Assembler.ConditionFlag.parity, l);
- jcc(AMD64Assembler.ConditionFlag.below, l);
- movl(dst, 0);
- jcc(AMD64Assembler.ConditionFlag.equal, l);
- incrementl(dst, 1);
- } else { // unordered is greater
- movl(dst, 1);
- jcc(AMD64Assembler.ConditionFlag.parity, l);
- jcc(AMD64Assembler.ConditionFlag.above, l);
- movl(dst, 0);
- jcc(AMD64Assembler.ConditionFlag.equal, l);
- decrementl(dst, 1);
- }
- bind(l);
- }
-
- void cmpptr(CiRegister src1, CiRegister src2) {
- cmpq(src1, src2);
- }
-
- void cmpptr(CiRegister src1, CiAddress src2) {
- cmpq(src1, src2);
- }
-
- void cmpptr(CiRegister src1, int src2) {
- cmpq(src1, src2);
- }
-
- void cmpptr(CiAddress src1, int src2) {
- cmpq(src1, src2);
- }
-
- void decrementl(CiRegister reg, int value) {
- if (value == Integer.MIN_VALUE) {
- subl(reg, value);
- return;
- }
- if (value < 0) {
- incrementl(reg, -value);
- return;
- }
- if (value == 0) {
- return;
- }
- if (value == 1 && C1XOptions.UseIncDec) {
- decl(reg);
- } else {
- subl(reg, value);
- }
- }
-
- void decrementl(CiAddress dst, int value) {
- if (value == Integer.MIN_VALUE) {
- subl(dst, value);
- return;
- }
- if (value < 0) {
- incrementl(dst, -value);
- return;
- }
- if (value == 0) {
- return;
- }
- if (value == 1 && C1XOptions.UseIncDec) {
- decl(dst);
- } else {
- subl(dst, value);
- }
- }
-
- void incrementl(CiRegister reg, int value) {
- if (value == Integer.MIN_VALUE) {
- addl(reg, value);
- return;
- }
- if (value < 0) {
- decrementl(reg, -value);
- return;
- }
- if (value == 0) {
- return;
- }
- if (value == 1 && C1XOptions.UseIncDec) {
- incl(reg);
- } else {
- addl(reg, value);
- }
- }
-
- void incrementl(CiAddress dst, int value) {
- if (value == Integer.MIN_VALUE) {
- addl(dst, value);
- return;
- }
- if (value < 0) {
- decrementl(dst, -value);
- return;
- }
- if (value == 0) {
- return;
- }
- if (value == 1 && C1XOptions.UseIncDec) {
- incl(dst);
- } else {
- addl(dst, value);
- }
- }
-
- void signExtendByte(CiRegister reg) {
- if (reg.isByte()) {
- movsxb(reg, reg); // movsxb
- } else {
- shll(reg, 24);
- sarl(reg, 24);
- }
- }
-
- void signExtendShort(CiRegister reg) {
- movsxw(reg, reg); // movsxw
- }
-
- // Support optimal SSE move instructions.
- void movflt(CiRegister dst, CiRegister src) {
- assert dst.isFpu() && src.isFpu();
- if (C1XOptions.UseXmmRegToRegMoveAll) {
- movaps(dst, src);
- } else {
- movss(dst, src);
- }
- }
-
- void movflt(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
- movss(dst, src);
- }
-
- void movflt(CiAddress dst, CiRegister src) {
- assert src.isFpu();
- movss(dst, src);
- }
-
- void movdbl(CiRegister dst, CiRegister src) {
- assert dst.isFpu() && src.isFpu();
- if (C1XOptions.UseXmmRegToRegMoveAll) {
- movapd(dst, src);
- } else {
- movsd(dst, src);
- }
- }
-
- void movdbl(CiRegister dst, CiAddress src) {
- assert dst.isFpu();
- if (C1XOptions.UseXmmLoadAndClearUpper) {
- movsd(dst, src);
- } else {
- movlpd(dst, src);
- }
- }
-
- void xchgptr(CiRegister src1, CiRegister src2) {
- xchgq(src1, src2);
- }
-
- public void shouldNotReachHere() {
- stop("should not reach here");
- }
-
- public void enter(short imm16, byte imm8) {
- emitByte(0xC8);
- // appended:
- emitByte(imm16 & 0xff);
- imm16 >>= 8;
- emitByte(imm16 & 0xff);
- emitByte(imm8);
- }
-
- /**
- * Emit code to save a given set of callee save registers to the
- * {@linkplain CiCalleeSaveArea CSA} within the frame.
- * @param csa the description of the CSA
- * @param frameToCSA offset from the frame pointer to the CSA
- */
- public void save(CiCalleeSaveArea csa, int frameToCSA) {
- CiRegisterValue frame = frameRegister.asValue();
- for (CiRegister r : csa.registers) {
- int offset = csa.offsetOf(r);
- movq(new CiAddress(CiKind.Word, frame, frameToCSA + offset), r);
- }
- }
-
- public void restore(CiCalleeSaveArea csa, int frameToCSA) {
- CiRegisterValue frame = frameRegister.asValue();
- for (CiRegister r : csa.registers) {
- int offset = csa.offsetOf(r);
- movq(r, new CiAddress(CiKind.Word, frame, frameToCSA + offset));
- }
- }
-
- public void int3() {
- emitByte(0xCC);
- }
-}
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64XirAssembler.java
--- a/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64XirAssembler.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64XirAssembler.java Fri May 13 17:09:20 2011 -0700
@@ -26,6 +26,7 @@
import java.util.*;
+import com.oracle.max.asm.target.amd64.*;
import com.sun.c1x.util.*;
import com.sun.cri.ci.*;
import com.sun.cri.xir.*;
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalRuntime/.classpath
--- a/graal/GraalRuntime/.classpath Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalRuntime/.classpath Fri May 13 17:09:20 2011 -0700
@@ -1,10 +1,11 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalRuntime/src/com/oracle/graal/runtime/CompilerImpl.java
--- a/graal/GraalRuntime/src/com/oracle/graal/runtime/CompilerImpl.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalRuntime/src/com/oracle/graal/runtime/CompilerImpl.java Fri May 13 17:09:20 2011 -0700
@@ -28,8 +28,8 @@
import com.oracle.graal.runtime.logging.*;
import com.oracle.graal.runtime.server.*;
+import com.oracle.max.asm.target.amd64.*;
import com.sun.c1x.*;
-import com.sun.c1x.target.amd64.*;
import com.sun.cri.ci.*;
import com.sun.cri.ri.*;
import com.sun.cri.xir.*;
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotRegisterConfig.java
--- a/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotRegisterConfig.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotRegisterConfig.java Fri May 13 17:09:20 2011 -0700
@@ -22,11 +22,11 @@
*/
package com.oracle.graal.runtime;
-import static com.sun.c1x.target.amd64.AMD64.*;
+import static com.oracle.max.asm.target.amd64.AMD64.*;
import java.util.*;
-import com.sun.c1x.target.amd64.*;
+import com.oracle.max.asm.target.amd64.*;
import com.sun.c1x.util.*;
import com.sun.cri.ci.*;
import com.sun.cri.ci.CiCallingConvention.Type;
diff -r e0e89714e2f1 -r 0ea5f12e873a graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotXirGenerator.java
--- a/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotXirGenerator.java Fri May 13 14:03:03 2011 -0700
+++ b/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotXirGenerator.java Fri May 13 17:09:20 2011 -0700
@@ -29,17 +29,14 @@
import java.util.*;
import java.util.concurrent.*;
-import com.sun.c1x.target.amd64.*;
-import com.sun.cri.ci.CiAddress.Scale;
+import com.oracle.max.asm.target.amd64.*;
+import com.sun.cri.ci.*;
+import com.sun.cri.ci.CiAddress.*;
import com.sun.cri.ci.CiRegister.*;
-import com.sun.cri.ci.*;
import com.sun.cri.ri.*;
-import com.sun.cri.ri.RiType.Representation;
+import com.sun.cri.ri.RiType.*;
import com.sun.cri.xir.*;
-import com.sun.cri.xir.CiXirAssembler.XirLabel;
-import com.sun.cri.xir.CiXirAssembler.XirMark;
-import com.sun.cri.xir.CiXirAssembler.XirOperand;
-import com.sun.cri.xir.CiXirAssembler.XirParameter;
+import com.sun.cri.xir.CiXirAssembler.*;
public class HotSpotXirGenerator implements RiXirGenerator {
diff -r e0e89714e2f1 -r 0ea5f12e873a src/share/vm/runtime/arguments.cpp
--- a/src/share/vm/runtime/arguments.cpp Fri May 13 14:03:03 2011 -0700
+++ b/src/share/vm/runtime/arguments.cpp Fri May 13 17:09:20 2011 -0700
@@ -2688,6 +2688,8 @@
scp_p->add_prefix(temp);
sprintf(temp, "%s/Assembler/bin", maxine_dir);
scp_p->add_prefix(temp);
+ sprintf(temp, "%s/com.oracle.max.asm/bin", maxine_dir);
+ scp_p->add_prefix(temp);
sprintf(temp, "%s/graal/GraalCompiler/bin", graal_dir);
scp_p->add_prefix(temp);
sprintf(temp, "%s/graal/GraalRuntime/bin", graal_dir);