summaryrefslogtreecommitdiff
path: root/chapter19/src
diff options
context:
space:
mode:
Diffstat (limited to 'chapter19/src')
-rw-r--r--chapter19/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java7
-rw-r--r--chapter19/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java6
-rw-r--r--chapter19/src/test/java/com/seaofnodes/simple/IndirectCallTest.java28
3 files changed, 37 insertions, 4 deletions
diff --git a/chapter19/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java b/chapter19/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
index 02850582..09855b7d 100644
--- a/chapter19/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
+++ b/chapter19/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
@@ -1,17 +1,20 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.simple.type.TypeFunPtr;
import com.seaofnodes.simple.*;
import com.seaofnodes.simple.node.*;
import java.io.ByteArrayOutputStream;
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 label() { return op(); }
@Override public RegMask regmap(int i) {
// Todo: float or int?
- return i==_inputs._len
+ return i==_inputs._len-1
? riscv.RMASK // Function call target
: riscv.callInMaskInt(i); // Normal argument
}
diff --git a/chapter19/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java b/chapter19/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java
index 99260a27..c170d7e4 100644
--- a/chapter19/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java
+++ b/chapter19/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java
@@ -7,11 +7,13 @@ import com.seaofnodes.simple.type.TypeFunPtr;
import java.io.ByteArrayOutputStream;
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 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); // Normal argument
}
diff --git a/chapter19/src/test/java/com/seaofnodes/simple/IndirectCallTest.java b/chapter19/src/test/java/com/seaofnodes/simple/IndirectCallTest.java
new file mode 100644
index 00000000..6daa4354
--- /dev/null
+++ b/chapter19/src/test/java/com/seaofnodes/simple/IndirectCallTest.java
@@ -0,0 +1,28 @@
+package com.seaofnodes.simple;
+
+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"} ) {
+ CodeGen code = new CodeGen("return 0;").driver(CodeGen.Phase.InstructionSelection,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.get(5));
+ assertTrue(mask.get(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());
+ }
+ }
+}