summaryrefslogtreecommitdiff
path: root/chapter24/src/test/java
diff options
context:
space:
mode:
Diffstat (limited to 'chapter24/src/test/java')
-rw-r--r--chapter24/src/test/java/com/seaofnodes/simple/Chapter20Test.java17
-rw-r--r--chapter24/src/test/java/com/seaofnodes/simple/Chapter21Test.java32
-rw-r--r--chapter24/src/test/java/com/seaofnodes/simple/EvalArm64.java14
-rw-r--r--chapter24/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java13
4 files changed, 69 insertions, 7 deletions
diff --git a/chapter24/src/test/java/com/seaofnodes/simple/Chapter20Test.java b/chapter24/src/test/java/com/seaofnodes/simple/Chapter20Test.java
index 70ddd435..044ad4ed 100644
--- a/chapter24/src/test/java/com/seaofnodes/simple/Chapter20Test.java
+++ b/chapter24/src/test/java/com/seaofnodes/simple/Chapter20Test.java
@@ -11,6 +11,23 @@ import org.junit.Test;
import static org.junit.Assert.*;
public class Chapter20Test {
+ @Test public void testAllocatorFixedNeighbor() throws Exception { com.seaofnodes.simple.codegen.RegAllocTestSupport.uncoloredFixedNeighbor(); }
+
+ @Test public void testNarrowStoreMasks() {
+ for( String type : new String[]{"i8","u8","i16","u16"} ) {
+ CodeGen code = new CodeGen("struct S { "+type+" x; }; S !s=new S; s.x=arg; return 0;")
+ .driver(CodeGen.Phase.RegAlloc,"x86_64_v2","SystemV");
+ int stores=0;
+ for( var bb : code._cfg )
+ for( var node : bb.outs() )
+ if( node instanceof com.seaofnodes.simple.node.cpus.x86_64_v2.StoreX86 st ) {
+ stores++;
+ assertEquals(-1,st.regmap(4).nextReg((short)15));
+ }
+ assertEquals(1,stores);
+ }
+ }
+
@Test public void testInlinedReturnValue() {
String src = """
struct S { int x; };
diff --git a/chapter24/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter24/src/test/java/com/seaofnodes/simple/Chapter21Test.java
index 7b22389e..afa99d31 100644
--- a/chapter24/src/test/java/com/seaofnodes/simple/Chapter21Test.java
+++ b/chapter24/src/test/java/com/seaofnodes/simple/Chapter21Test.java
@@ -13,6 +13,38 @@ import org.junit.Test;
import static org.junit.Assert.*;
public class Chapter21Test {
+ @Test public void testArmFloatMemory() throws IOException {
+ for( String type : new String[]{"f32","f64"} ) {
+ String src = type+"[] !a=new "+type+"[3]; a[arg]=1.25; return a[1];";
+ CodeGen code = new CodeGen(src).driver("arm","SystemV",null);
+ byte[] image = new byte[1<<20];
+ byte[] bits = code._encoding.bits();
+ System.arraycopy(bits,0,image,0,bits.length);
+ EvalArm64 cpu = new EvalArm64(image,1<<16);
+ cpu.regs[arm.X0]=1;
+ assertEquals(0,cpu.step(1000));
+ assertEquals(1.25,cpu.fregs[0],0);
+ }
+ // Independently exercise both SIMD widths and addressing modes. Keep
+ // the GPR value different so accidentally reading that bank is visible.
+ for( boolean wide : new boolean[]{false,true} )
+ for( boolean indexed : new boolean[]{false,true} ) {
+ EvalArm64 cpu = new EvalArm64(new byte[512],256);
+ cpu.regs[1]=128; cpu.regs[2]=16; cpu.regs[3]=99;
+ cpu.fregs[3]=-13.25;
+ int store = (wide ? 0xFD000000 : 0xBD000000) | ((16/(wide?8:4))<<10) | (1<<5) | 3;
+ if( indexed ) store=(wide ? 0xFC226823 : 0xBC226823); // STR D3/S3,[X1,X2]
+ cpu.st4(0,store);
+ cpu.st4(4,store | (1<<22)); // LDR to the same SIMD register.
+ assertEquals(0,cpu.step(1));
+ assertEquals(-13.25,wide ? cpu.ld8f(144) : cpu.ld4f(144),0);
+ cpu.fregs[3]=0;
+ assertEquals(0,cpu.step(1));
+ assertEquals(-13.25,cpu.fregs[3],0);
+ }
+ }
+
+
@Test public void testArmCallInstructions() {
EvalArm64 cpu = new EvalArm64(new byte[512],256);
for( int delta : new int[]{4,32,-4} ) {
diff --git a/chapter24/src/test/java/com/seaofnodes/simple/EvalArm64.java b/chapter24/src/test/java/com/seaofnodes/simple/EvalArm64.java
index 5557de3c..5dc56ef7 100644
--- a/chapter24/src/test/java/com/seaofnodes/simple/EvalArm64.java
+++ b/chapter24/src/test/java/com/seaofnodes/simple/EvalArm64.java
@@ -488,7 +488,7 @@ public class EvalArm64 {
switch(opc) {
case 0x1: {
if(opcode1 == arm.OPF_STORE_R_32) {
- st4((int)regs[rn] + (int)regs[rm], (int)regs[rdid]);
+ st4((int)regs[rn] + (int)regs[rm], Float.floatToRawIntBits((float)fregs[rdid]));
}else {
trap = (2+1);
}
@@ -527,7 +527,7 @@ public class EvalArm64 {
case 0x0: {
// store
if(opcode1 == arm.OPF_STORE_IMM_32) {
- st4((int)rval, (int)regs[rdid]);
+ st4((int)rval, Float.floatToRawIntBits((float)fregs[rdid]));
} else trap = (2+1);
rdid = -1;
@@ -536,7 +536,7 @@ public class EvalArm64 {
case 0x1: {
// LDR (immediate)
if(opcode1 == arm.OPF_LOAD_IMM_32) {
- frval = ld4s((int)rval);
+ frval = ld4f((int)rval);
} else trap = (2+1);
break;
}
@@ -690,7 +690,7 @@ public class EvalArm64 {
switch(opc) {
case 0x1: {
if(opcode1 == arm.OPF_STORE_R_64) {
- st8((int)regs[rn] + (int)regs[rm], (int)regs[rdid]);
+ st8((int)regs[rn] + (int)regs[rm], Double.doubleToRawLongBits(fregs[rdid]));
}else {
trap = (2+1);
}
@@ -718,7 +718,7 @@ public class EvalArm64 {
int base = ir >> 5 & 0x1F;
int imm = (ir >> 10) & 0xFFF;
- imm *= 4;
+ imm *= 8;
is_f = true;
rval = regs[base] + imm;
int opc = (ir >> 22) & 0x3;
@@ -728,7 +728,7 @@ public class EvalArm64 {
case 0x0: {
// store
if(opcode1 == arm.OPF_STORE_IMM_64) {
- st8((int)rval, regs[rdid]);
+ st8((int)rval, Double.doubleToRawLongBits(fregs[rdid]));
} else trap = (2+1);
rdid = -1;
@@ -737,7 +737,7 @@ public class EvalArm64 {
case 0x1: {
// LDR (immediate)
if(opcode1 == arm.OPF_LOAD_IMM_64) {
- frval = ld8((int)rval);
+ frval = ld8f((int)rval);
} else trap = (2+1);
break;
}
diff --git a/chapter24/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java b/chapter24/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java
index 20da40fd..c0a26d60 100644
--- a/chapter24/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java
+++ b/chapter24/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java
@@ -29,6 +29,19 @@ public class RegAllocTestSupport {
return code;
}
+ public static void uncoloredFixedNeighbor() throws Exception {
+ CodeGen code = graph();
+ RegAlloc alloc = new RegAlloc(code);
+ Op def = new Op(new RegMask(3L),null,null,false,code._start);
+ LRG lrg = alloc.newLRG(def);
+ LRG neighbor = new LRG((short)99);
+ neighbor._mask = A;
+ lrg.addNeighbor(neighbor); // Uncolored, but its only possible color is A.
+ var bias = IFG.class.getDeclaredMethod("biasColorNeighbors",RegAlloc.class,Node.class,RegMask.class);
+ bias.setAccessible(true);
+ assertEquals((short)1,bias.invoke(null,alloc,def,new RegMaskRW(3L,0L)));
+ }
+
public static void masks() {
for( int reg : new int[]{0,63,64,65,127} ) {
RegMask mask = new RegMask(reg);