summaryrefslogtreecommitdiff
path: root/chapter21/src/test/java/com/seaofnodes/simple/IndirectCallTest.java
blob: 213594ba98045ac62729f22660e4215a174356d8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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.InstSelect,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());
        }
    }
}