summaryrefslogtreecommitdiff
path: root/chapter22/src/main/java
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-05-05 21:24:06 -0700
committerCliff Click <cliffc@acm.org>2025-05-05 21:24:06 -0700
commit31f89ec8f8d2b05e2550b7c6957259380ef21575 (patch)
tree0553c3a64f555c5ee641573d35138d8fdab38e8c /chapter22/src/main/java
parent04881a0ea7e84cf8af05054946f10cc6bb14f8fc (diff)
downloadSimple-31f89ec8f8d2b05e2550b7c6957259380ef21575.tar.gz
Simple-31f89ec8f8d2b05e2550b7c6957259380ef21575.zip
Now with risc5
R5 eval handles extern `write` call.
Diffstat (limited to 'chapter22/src/main/java')
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java2
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java5
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java2
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java4
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TMPARM.java51
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java15
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java11
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java8
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java41
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java3
10 files changed, 118 insertions, 24 deletions
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java b/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
index 722320e8..da4f9ee7 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
@@ -498,6 +498,7 @@ public class Encoding {
// Since no runtime in the JVM process, using magic numbers for the CPU
// emulators to pick up on.
public static int SENTINAL_CALLOC = -4;
+ public static int SENTINAL_WRITE = -8;
void patchGlobalRelocations() {
for( Node src : _externals.keySet() ) {
@@ -505,6 +506,7 @@ public class Encoding {
String dst = _externals.get(src);
int target = switch( dst ) {
case "calloc" -> SENTINAL_CALLOC;
+ case "write" -> SENTINAL_WRITE ;
default -> throw Utils.TODO();
};
((RIPRelSize)src).patch(this, start, _opLen[src._nid], target - start);
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java
index 2823d7d1..d5e12b7f 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java
@@ -23,9 +23,12 @@ public class CallARM extends CallNode implements MachNode, RIPRelSize {
@Override public TypeFunPtr tfp() { return _tfp; }
@Override public RegMask regmap(int i) { return arm.callInMask(_tfp,i); }
@Override public RegMask outregmap() { return null; }
+ @Override public int nargs() { return nIns()-2; } // Minus control, memory, fptr
@Override public void encoding( Encoding enc ) {
- enc.relo(this);
+ FunNode fun = CodeGen.CODE.link(_tfp);
+ if( fun==null ) enc.external(this,_name);
+ else enc.relo(this);
// BL
enc.add4(arm.b(arm.OP_CALL,0)); // Target patched at link time
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java
index 6de65b03..63c57770 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java
@@ -20,8 +20,6 @@ public class FloatARM extends ConstantNode implements MachNode, RIPRelSize {
@Override public void encoding( Encoding enc ) {
enc.largeConstant(this,_con,0,-1/*TODO: ARM-style ELF patching*/);
short dst = (short)(enc.reg(this) - arm.D_OFFSET);
- double d = ((TypeFloat)_con).value();
- long x = Double.doubleToRawLongBits(d);
enc.add4(arm.load_pc(arm.OPF_ARM, 0, dst));
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java
index 76e23c30..908d46d0 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java
@@ -5,7 +5,6 @@ import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.ConstantNode;
import com.seaofnodes.simple.node.MachNode;
import com.seaofnodes.simple.node.Node;
-import com.seaofnodes.simple.node.cpus.riscv.riscv;
import com.seaofnodes.simple.type.TypeFunPtr;
public class TFPARM extends ConstantNode implements MachNode, RIPRelSize {
@@ -26,8 +25,7 @@ public class TFPARM extends ConstantNode implements MachNode, RIPRelSize {
}
@Override public byte encSize(int delta) {
- if( -(1L<<12) <= delta && delta < (1L<<12) ) return 4;
- throw Utils.TODO();
+ return 8;
}
// Delta is from opcode start
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TMPARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TMPARM.java
new file mode 100644
index 00000000..7600d66b
--- /dev/null
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TMPARM.java
@@ -0,0 +1,51 @@
+package com.seaofnodes.simple.node.cpus.arm;
+
+import com.seaofnodes.simple.*;
+import com.seaofnodes.simple.codegen.*;
+import com.seaofnodes.simple.node.ConstantNode;
+import com.seaofnodes.simple.node.MachNode;
+import com.seaofnodes.simple.node.Node;
+import com.seaofnodes.simple.type.TypeMemPtr;
+
+public class TMPARM extends ConstantNode implements MachNode, RIPRelSize {
+ TMPARM( ConstantNode con ) { super(con); }
+ @Override public String op() { return "ldp"; }
+ @Override public RegMask regmap(int i) { return null; }
+ @Override public RegMask outregmap() { return arm.WMASK; }
+ @Override public boolean isClone() { return true; }
+ @Override public TMPARM copy() { return new TMPARM(this); }
+ @Override public void encoding( Encoding enc ) {
+ enc.largeConstant(this,((TypeMemPtr)_con)._obj,0,-1);
+ short dst = enc.reg(this);
+ // adrp x0, 0
+ enc.add4(arm.adrp(1,0, arm.OP_ADRP, 0,dst));
+ // add x0, x0, 0
+ arm.imm_inst(enc,arm.OPI_ADD,0, dst);
+ }
+
+ @Override public byte encSize(int delta) {
+ return 8;
+ }
+
+ // Delta is from opcode start
+ @Override public void patch( Encoding enc, int opStart, int opLen, int delta ) {
+ short dst = enc.reg(this);
+ if(opLen == 8 ) {
+ // opstart of add
+ int next = opStart + opLen;
+ int adrp_delta = delta >> 12;
+ // patch upper 20 bits via adrp
+ enc.patch4(opStart, arm.adrp(1, adrp_delta & 0b11, 0b10000, adrp_delta >> 2, dst));
+ // low 12 bits via add
+ enc.patch4(next, arm.imm_inst_l(arm.OPI_ADD, delta & 0xfff, dst));
+ } else {
+ throw Utils.TODO();
+ }
+ }
+
+ @Override public void asm(CodeGen code, SB sb) {
+ String reg = code.reg(this);
+ _con.print(sb.p(reg).p(" #"));
+ }
+ @Override public boolean eq(Node n) { return this==n; }
+}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java
index 104929f4..d589dc7d 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java
@@ -567,6 +567,7 @@ public class arm extends Machine {
static RegMask callInMask(TypeFunPtr tfp, int idx ) {
if( idx==0 ) return CodeGen.CODE._rpcMask;
if( idx==1 ) return null;
+ if( idx-2 >= tfp.nargs() ) return null; // Anti-dependence
// Count floats in signature up to index
int fcnt=0;
for( int i=2; i<idx; i++ )
@@ -729,13 +730,13 @@ public class arm extends Machine {
private Node con( ConstantNode con ) {
if( !con._con.isConstant() ) return new ConstantNode( con ); // Default unknown caller inputs
return switch( con._con ) {
- case TypeInteger ti -> new IntARM(con);
- case TypeFloat tf -> new FloatARM(con);
- case TypeFunPtr tfp -> new TFPARM(con);
- case TypeMemPtr tmp -> new ConstantNode(con);
- case TypeNil tn -> throw Utils.TODO();
- // TOP, BOTTOM, XCtrl, Ctrl, etc. Never any executable code.
- case Type t -> t==Type.NIL ? new IntARM(con) : new ConstantNode(con);
+ case TypeInteger ti -> new IntARM(con);
+ case TypeFloat tf -> new FloatARM(con);
+ case TypeFunPtr tfp -> new TFPARM(con);
+ case TypeMemPtr tmp -> new TMPARM(con);
+ case TypeNil tn -> throw Utils.TODO();
+ // TOP, BOTTOM, XCtrl, Ctrl, etc. Never any executable code.
+ case Type t -> t==Type.NIL ? new IntARM(con) : new ConstantNode(con);
};
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java
index ad70a661..daef60f2 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java
@@ -19,17 +19,18 @@ public class CallRISC extends CallNode implements MachNode, RIPRelSize {
@Override public String op() { return "call"; }
@Override public String label() { return op(); }
- @Override public RegMask regmap(int i) {
- return riscv.callInMask(_tfp,i);
- }
- @Override public RegMask outregmap() { return riscv.RPC_MASK; }
@Override public String name() { return _name; }
@Override public TypeFunPtr tfp() { return _tfp; }
+ @Override public RegMask regmap(int i) { return riscv.callInMask(_tfp,i); }
+ @Override public RegMask outregmap() { return riscv.RPC_MASK; }
+ @Override public int nargs() { return nIns()-2; } // Minus control, memory, fptr
@Override public void encoding( Encoding enc ) {
// Short form +/-4K: beq r0,r0,imm12
// Long form: auipc rX,imm20/32; jal r0,[rX+imm12/32]
- enc.relo(this);
+ FunNode fun = CodeGen.CODE.link(_tfp);
+ if( fun==null ) enc.external(this,_name);
+ else enc.relo(this);
short rpc = enc.reg(this);
enc.add4(riscv.j_type(riscv.OP_JAL, rpc, 0));
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java
index a69cfbe8..15be82bc 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java
@@ -20,11 +20,9 @@ public class TFPRISC extends ConstantNode implements MachNode, RIPRelSize {
short dst = enc.reg(this);
TypeFunPtr tfp = (TypeFunPtr)_con;
// auipc t0,0
- int auipc = riscv.u_type(riscv.OP_AUIPC, dst, 0);
+ enc.add4(riscv.u_type(riscv.OP_AUIPC, dst, 0));
// addi t1,t0 + #0
- int addi = riscv.i_type(riscv.OP_IMM, dst, 0, dst, 0);
- enc.add4(auipc);
- enc.add4(addi);
+ enc.add4(riscv.i_type(riscv.OP_IMM, dst, 0, dst, 0));
}
@Override public byte encSize(int delta) {
@@ -39,7 +37,7 @@ public class TFPRISC extends ConstantNode implements MachNode, RIPRelSize {
// AUIPC (upper 20 bits)
// opstart of add
int next = opStart + opLen;
- enc.patch4(opStart,riscv.u_type(riscv.OP_AUIPC, rpc, delta));
+ enc.patch4(opStart,riscv.u_type(riscv.OP_AUIPC, rpc, delta>>12));
// addi(low 12 bits)
enc.patch4(next,riscv.i_type(riscv.OP_IMM, rpc, 0, rpc, delta & 0xFFF));
// addi
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java
new file mode 100644
index 00000000..860e5eaf
--- /dev/null
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java
@@ -0,0 +1,41 @@
+package com.seaofnodes.simple.node.cpus.riscv;
+
+import com.seaofnodes.simple.*;
+import com.seaofnodes.simple.codegen.*;
+import com.seaofnodes.simple.node.ConstantNode;
+import com.seaofnodes.simple.node.MachNode;
+import com.seaofnodes.simple.node.Node;
+import com.seaofnodes.simple.type.TypeMemPtr;
+
+public class TMPRISC extends ConstantNode implements MachNode, RIPRelSize {
+ TMPRISC(ConstantNode con) { super(con); }
+ @Override public String op() { return "ldp"; }
+ @Override public RegMask regmap(int i) { return null; }
+ @Override public RegMask outregmap() { return riscv.WMASK; }
+ @Override public boolean isClone() { return true; }
+ @Override public TMPRISC copy() { return new TMPRISC(this); }
+ @Override public void encoding( Encoding enc ) {
+ enc.largeConstant(this,((TypeMemPtr)_con)._obj,0,-1);
+ short dst = enc.reg(this);
+ // AUIPC dst,#hi20_constant_pool
+ enc.add4(riscv.u_type(riscv.OP_AUIPC, dst, 0));
+ // addi dst,[dst+#low12_constant_pool]
+ enc.add4(riscv.i_type(riscv.OP_IMM, dst, 0, dst, 0));
+ }
+
+ @Override public byte encSize(int delta) { return 8; }
+
+ // Delta is from opcode start
+ @Override public void patch( Encoding enc, int opStart, int opLen, int delta ) {
+ short dst = enc.reg(this);
+ // AUIPC dst,#hi20_constant_pool
+ enc.patch4(opStart , riscv.u_type(riscv.OP_AUIPC, dst, delta>>12));
+ // Load dst,[dst+#low12_constant_pool]
+ enc.patch4(opStart+4, riscv.i_type(riscv.OP_IMM, dst, 0, dst, delta & 0xFFF));
+ }
+
+ @Override public void asm(CodeGen code, SB sb) {
+ _con.print(sb.p(code.reg(this)).p(" #"));
+ }
+ @Override public boolean eq(Node n) { return this==n; }
+}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java
index 699b867e..c4cde159 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java
@@ -256,6 +256,7 @@ public class riscv extends Machine {
static RegMask callInMask( TypeFunPtr tfp, int idx ) {
if( idx==0 ) return RPC_MASK;
if( idx==1 ) return null;
+ if( idx-2 >= tfp.nargs() ) return null; // Anti-dependence
// Count floats in signature up to index
int fcnt=0;
for( int i=2; i<idx; i++ )
@@ -446,7 +447,7 @@ public class riscv extends Machine {
// Load from constant pool
case TypeFloat tf -> new FltRISC(con);
case TypeFunPtr tfp -> new TFPRISC(con);
- case TypeMemPtr tmp -> throw Utils.TODO();
+ case TypeMemPtr tmp -> new TMPRISC(con);
case TypeNil tn -> throw Utils.TODO();
// TOP, BOTTOM, XCtrl, Ctrl, etc. Never any executable code.
case Type t -> t==Type.NIL ? new IntRISC(con) : new ConstantNode(con);