summaryrefslogtreecommitdiff
path: root/chapter24b/src
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-10-27 19:06:47 -0700
committerCliff Click <cliffc@acm.org>2026-10-27 19:06:47 -0700
commit19f9ea99114e9c1819239508f812d6521661f7bb (patch)
treedf8b80611f04faceb0e64880bb70eaf17a08c2b6 /chapter24b/src
parenteb9f6b86720c8a5c6c66e1c1837c65a4637aabee (diff)
downloadSimple-19f9ea99114e9c1819239508f812d6521661f7bb.tar.gz
Simple-19f9ea99114e9c1819239508f812d6521661f7bb.zip
Backport a bunch of fixes
ARM encoding Extra fidx burned with no constructor Getting types during a parse to avoid a whole-program walk later
Diffstat (limited to 'chapter24b/src')
-rw-r--r--chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java9
-rw-r--r--chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java5
-rw-r--r--chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java7
-rw-r--r--chapter24b/src/test/java/com/seaofnodes/simple/IndirectCallTest.java30
4 files changed, 45 insertions, 6 deletions
diff --git a/chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java b/chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java
index 1949ae46..856af3b8 100644
--- a/chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java
+++ b/chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java
@@ -1,16 +1,19 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.simple.type.TypeFunPtr;
import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
public class CallRRARM extends CallNode implements MachNode {
- CallRRARM(CallNode call) { super(call); }
+ final TypeFunPtr _tfp;
+ CallRRARM( CallNode call ) { super(call); _tfp = call.tfp(); }
+ @Override public TypeFunPtr tfp() { return _tfp; }
@Override public String op() { return "callr"; }
@Override public String label() { return op(); }
@Override public RegMask regmap(int i) {
- return i==_inputs._len
+ return i==_inputs._len-1
? arm.RMASK // Function call target
: arm.callInMask(tfp(),i,fun()._maxArgSlot); // Normal argument
}
@@ -19,7 +22,7 @@ public class CallRRARM extends CallNode implements MachNode {
@Override public void encoding( Encoding enc ) {
// Needs a register, typically a jump-and-link-register opcode
// blr
- short self = enc.reg(this);
+ short self = enc.reg(fptr());
enc.add4(Arm64.blr(Arm64.OP_CALLRARM, self));
}
diff --git a/chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java b/chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
index 5eee596d..ffd47713 100644
--- a/chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
+++ b/chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
@@ -1,12 +1,15 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.simple.type.TypeFunPtr;
import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
public class CallRRISC extends CallNode implements MachNode {
- CallRRISC( CallNode call ) { super(call); }
+ final TypeFunPtr _tfp;
+ CallRRISC( CallNode call ) { super(call); _tfp = call.tfp(); }
+ @Override public TypeFunPtr tfp() { return _tfp; }
@Override public String op() { return "callr"; }
@Override public String label() { return op(); }
@Override public RegMask regmap(int i) {
diff --git a/chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java b/chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java
index f97163eb..c204f25c 100644
--- a/chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java
+++ b/chapter24b/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.simple.type.TypeFunPtr;
import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.CallNode;
@@ -7,11 +8,13 @@ import com.seaofnodes.simple.node.MachNode;
import com.seaofnodes.simple.util.SB;
public class CallRX86 extends CallNode implements MachNode {
- CallRX86( CallNode call ) { super(call); }
+ final TypeFunPtr _tfp;
+ CallRX86( CallNode call ) { super(call); _tfp = call.tfp(); }
+ @Override public TypeFunPtr tfp() { return _tfp; }
@Override public String op() { return "callr"; }
@Override public String label() { return op(); }
@Override public RegMask regmap(int i) {
- return i==_inputs._len
+ return i==_inputs._len-1
? x86_64_v2.WMASK // Function call target
: x86_64_v2.callInMask(tfp(),i,fun()._maxArgSlot); // Normal argument
}
diff --git a/chapter24b/src/test/java/com/seaofnodes/simple/IndirectCallTest.java b/chapter24b/src/test/java/com/seaofnodes/simple/IndirectCallTest.java
new file mode 100644
index 00000000..9bd1a342
--- /dev/null
+++ b/chapter24b/src/test/java/com/seaofnodes/simple/IndirectCallTest.java
@@ -0,0 +1,30 @@
+package com.seaofnodes.simple;
+
+import com.seaofnodes.simple.codegen.CodeGen;
+import com.seaofnodes.simple.codegen.RegMask;
+import com.seaofnodes.simple.node.*;
+import com.seaofnodes.simple.type.Type;
+import com.seaofnodes.simple.type.TypeFunPtr;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class IndirectCallTest {
+ @Test public void testTargetOperand() {
+ for( String cpu : new String[]{"x86_64_v2","riscv","arm"} ) {
+ CodeGen code = new CodeGen("return 0;").driver(CodeGen.Phase.Select,cpu,"SystemV");
+ Node target = PhiNode.make("target",TypeFunPtr.BOT,code._start);
+ target._type = TypeFunPtr.BOT;
+ CallNode ideal = new CallNode(null,code._start,null,target);
+ CallNode call = (CallNode)code._mach.instSelect(ideal);
+ // The last input is the call target, not another argument.
+ assertEquals("callr",((MachNode)call).op());
+ RegMask mask = ((MachNode)call).regmap(call.nIns()-1);
+ assertTrue(mask.test(5));
+ assertTrue(mask.test(6));
+ // Machine operands can lose their ideal type (e.g. a spill reload).
+ // The call still needs the original signature for argument masks.
+ target._type = Type.BOTTOM;
+ assertSame(TypeFunPtr.BOT,call.tfp());
+ }
+ }
+}