summaryrefslogtreecommitdiff
path: root/chapter21/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'chapter21/src/main')
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java25
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java4
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java59
3 files changed, 56 insertions, 32 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java
index 13abd93b..01faba52 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java
@@ -6,14 +6,21 @@ import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.TypeFunPtr;
public class NewX86 extends NewNode implements MachNode {
+ public static final String OS = System.getProperty("os.name");
+ public static final RegMask ARG2 = OS.startsWith("Windows")
+ ? x86_64_v2.callWin64(TypeFunPtr.CALLOC,2)
+ : x86_64_v2.callSys5 (TypeFunPtr.CALLOC,2);
+ public static final RegMask ARG3 = OS.startsWith("Windows")
+ ? x86_64_v2.callWin64(TypeFunPtr.CALLOC,3)
+ : x86_64_v2.callSys5 (TypeFunPtr.CALLOC,3);
+
// A pre-zeroed chunk of memory.
NewX86( NewNode nnn ) { super(nnn); }
@Override public String op() { return "alloc"; }
// Size and pointer result in standard calling convention; null for all the
// memory aliases edges
@Override public RegMask regmap(int i) {
- // Any { int->int } signature will do, as they all pick the same registers
- return i==1 ? x86_64_v2.callInMask(TypeFunPtr.CALLOC,3) : null;
+ return i==1 ? ARG2 : null;
}
@Override public RegMask outregmap(int i) { return i == 1 ? x86_64_v2.RAX_MASK : null; }
@Override public RegMask outregmap() { return null; }
@@ -21,18 +28,10 @@ public class NewX86 extends NewNode implements MachNode {
@Override public void encoding( Encoding enc ) {
enc.external(this,"calloc");
- short r1 = x86_64_v2.callInMask(TypeFunPtr.CALLOC,2).firstReg();
+ // This has to call the *native* ABI, irregardless of how Simple is
+ // being compiled, because it links against the native calloc.
// ldi rcx,#1 // number of elements to calloc
- enc.add1(0xB8 + r1).add4(1);
-
- //enc.add1(x86_64_v2.rex(0, dst, 0));
- //// opcode; 0x81 or 0x83; 0x69 or 0x6B
- //enc.add1( opcode() + 2 );
- //enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, mod(), dst) );
- //// immediate(4 bytes) 32 bits or (1 byte)8 bits
- //enc.add1(_imm);
-
-
+ enc.add1(0xB8 + ARG3.firstReg()).add4(1);
// E8 cd CALL rel32;
enc.add1(0xE8);
enc.add4(0); // offset
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java
index 5fbd1f02..ac5de47d 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java
@@ -57,8 +57,10 @@ public class StoreX86 extends MemOpX86 {
src -= (short)x86_64_v2.XMM_OFFSET;
enc.add1( decl==TypeFloat.F32 ? 0xF3 : 0xF2 ).add1(0x0F).add1(0x11);
} else {
+ // byte stores from sil, dil, bpl, spl need a rex
int log = decl.log_size();
- x86_64_v2.rexF(src,ptr,idx,log==3,enc);
+ if( log == 0 && src >= x86_64_v2.RSP ) enc.add1(x86_64_v2.rex(src,ptr,idx,false));
+ else x86_64_v2.rexF(src,ptr,idx,log==3,enc);
switch( log ) {
case 0: enc .add1(0x88); break;
case 1: enc.add1(0x66).add1(0x89); break;
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
index 2f70dc0c..7683177f 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
@@ -221,40 +221,63 @@ public class x86_64_v2 extends Machine {
}
// Win64 - max *4* args in registers of all kinds; after that on stack.
- // Stack args land in increasing memory order.
- // foo( int arg0, int arg1, int arg2, int arg3, int stk1, flt stk2, int stk3, ... )
+ // Stack args land in increasing memory order with empty/mirror slots for
+ // every register.
+ //
+ // foo( int i0, flt f1, int i2, flt f3, int i4, flt f5, int i6, ... )
//
// -- Prior Frame --
- // RPC
- // stk3
- // stk2
- // stk1
+ // i6
+ // f5
+ // i4
+ // empty mirror, XMM3= f3
+ // empty mirror, R08 = i2
+ // empty mirror, XMM1= f1
+ // empty mirror, RCX = i0
// -- Caller Frame; 16b align --
// RPC
- // PAD
+ // PAD/ALIGN
// -- Callee Frame; 16b align --
- static RegMask[] CALLINMASK_WIN64 = new RegMask[] {
+ static RegMask[] WIN64_CALL = new RegMask[] {
RCX_MASK,
RDX_MASK,
R08_MASK,
R09_MASK,
};
- private static RegMask callWin64(TypeFunPtr tfp, int idx ) {
- // idx 2,3,4,5 passed in registers, with stack slot mirrors
- // idx >= 6 passed on stack, starting at slot#1 (#0 reserved for RPC)
+ static RegMask callWin64(TypeFunPtr tfp, int idx ) {
+ // idx 2,3,4,5 passed in registers, with stack slot mirrors.
+ // idx >= 6 passed on stack, starting at slot#1 (#0 reserved for RPC).
if( idx >= 6 )
return new RegMask(MAX_REG+1/*RPC*/+(idx-2));
return tfp.arg(idx-2) instanceof TypeFloat
- ? XMMS8[idx-2]
- : CALLINMASK_WIN64[idx-2];
+ ? XMMS8 [idx-2]
+ : WIN64_CALL[idx-2];
}
static short maxArgSlotWin64(TypeFunPtr tfp) {
return (short)(1/*RPC*/+ tfp.nargs());
}
+ // Sys5: max 6 GPRs and 8 FPRS filled first. Extra args land in increasing
+ // memory order as needed - no mirror space.
+ //
+ // foo( int i0, flt f1, int i2, flt f3, int i4, flt f5, int i6, ... )
+ // RDI =i0, RSI =i2, RDX =i4, RCX =i6, R08 =i8, R09 =i10
+ // XMM0=f1, XMM1=f3, XMM2=f5, XMM3=f7, XMM4=f9, XMM5=f11, XMM6=f13, XMM7=f15
+ //
+ // -- Prior Frame --
+ // f18
+ // i18
+ // f17
+ // i16
+ // i14
+ // i12
+ // -- Caller Frame; 16b align --
+ // RPC
+ // PAD/ALIGN
+ // -- Callee Frame; 16b align --
// SystemV(param passing)
- static RegMask[] CALLINMASK_SYSTEMV = new RegMask[] {
+ static RegMask[] SYS5_CALL = new RegMask[] {
RDI_MASK,
RSI_MASK,
RDX_MASK,
@@ -263,7 +286,7 @@ public class x86_64_v2 extends Machine {
R09_MASK,
};
- private static RegMask callSys5(TypeFunPtr tfp, int idx ) {
+ static RegMask callSys5(TypeFunPtr tfp, int idx ) {
// First 6 integers passed in registers: rdi,rsi,rdx,rcx,r08,r09
// First 8 floats passed in registers: xmm0-xmm7
int icnt=0, fcnt=0; // Count of ints, floats
@@ -273,8 +296,8 @@ public class x86_64_v2 extends Machine {
}
int nstk = Math.max(icnt-6,0)+Math.max(fcnt-8,0);
return tfp.arg(idx-2) instanceof TypeFloat
- ? fcnt<8 ? XMMS8 [fcnt] : new RegMask(MAX_REG+nstk)
- : icnt<6 ? CALLINMASK_SYSTEMV[icnt] : new RegMask(MAX_REG+nstk);
+ ? fcnt<8 ? XMMS8 [fcnt] : new RegMask(MAX_REG+1/*RPC*/+nstk)
+ : icnt<6 ? SYS5_CALL[icnt] : new RegMask(MAX_REG+1/*RPC*/+nstk);
}
static short maxArgSlotSys5(TypeFunPtr tfp) {
int icnt=0, fcnt=0; // Count of ints, floats
@@ -283,7 +306,7 @@ public class x86_64_v2 extends Machine {
else icnt++;
}
int nstk = Math.max(icnt-6,0)+Math.max(fcnt-8,0);
- return (short)(1+nstk);
+ return (short)(1/*RPC*/+nstk);
}
// caller saved(systemv)