summaryrefslogtreecommitdiff
path: root/chapter21/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'chapter21/src/test')
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java17
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java22
2 files changed, 27 insertions, 12 deletions
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
index 72041bd7..6c943904 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
@@ -11,6 +11,23 @@ import org.junit.Test;
import static org.junit.Assert.*;
public class Chapter21Test {
+
+ @Test public void testArmBitfieldExtracts() {
+ // Independent SXT/UXT instruction words, plus ASR, LSR and LSL aliases.
+ int[] ops = {0x93401c20,0xd3401c20,0x93403c20,0xd3403c20,
+ 0x93407c20,0xd3407c20,0x9344fc20,0xd344fc20,0xd37cec20};
+ long value = 0xa5a5a5a580008080L;
+ long[] expected = {(byte)value,value&255,(short)value,value&65535,
+ (int)value,value&0xffffffffL,value>>4,value>>>4,value<<4};
+ for( int i=0; i<ops.length; i++ ) {
+ EvalArm64 cpu = new EvalArm64(new byte[1<<16],1<<15);
+ cpu.st4(0,ops[i]); cpu.regs[1]=value;
+ assertEquals(0,cpu.step(1));
+ assertEquals(expected[i],cpu.regs[0]);
+ }
+ }
+
+
@Test public void testReturnedFunctionEncoding() throws IOException {
String src = "if(arg) return {->42;}; return {->43;};";
CodeGen code = new CodeGen(src).driver("riscv","SystemV",null);
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java b/chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java
index 75525133..e5aa729b 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java
@@ -641,20 +641,18 @@ public class EvalArm64 {
rval = opcode1==0x91 ? regs[rn] + immediate : regs[rn] - immediate;
break;
}
- case 0xD3: {
- // lsl(immediate)
- int imm = (ir >> 16) & 0x3F;
- int rn = (ir >> 5) & 0x1F;
- rval = regs[rn] << (64 - imm);
- break;
- }
- case 0x93: {
- // asr(immediate)
- int imm = (ir >> 16) & 0x3F;
- int rn = (ir >> 5) & 0x1F;
- rval = regs[rn] >> (imm);
+ case 0x93, 0xD3: { // SBFM/UBFM: shifts and signed/unsigned extracts
+ int immr = (ir >>> 16) & 63;
+ int imms = (ir >>> 10) & 63;
+ int rn = (ir >>> 5) & 31;
+ boolean signed = (ir & 0x40000000)==0;
+ long value = regs[rn] << (63-imms);
+ value = signed ? value >> (63-imms) : value >>> (63-imms);
+ rval = immr > imms ? value << (64-immr)
+ : signed ? value >> immr : value >>> immr;
break;
}
+
case 0x92: {
// and(immediate)
int imm12 = (ir >> 10) & 0x1FFF;