summaryrefslogtreecommitdiff
path: root/chapter21/src/main/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'chapter21/src/main/java/com')
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java37
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java4
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java4
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java17
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java14
7 files changed, 61 insertions, 20 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java
index f9b53f6b..9f9c6db6 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java
@@ -20,10 +20,39 @@ public class IntARM extends ConstantNode implements MachNode {
@Override public void encoding( Encoding enc ) {
short self = enc.reg(this);
long x = ((TypeInteger)_con).value();
- if( (short)x == x )
- enc.add4(arm.mov(485, 0, (int)(x&0xFFFF), self));
- else
- throw Utils.TODO("Handle cases bigger than 16 bits");
+ int nb0 = 0;
+ int nb1 = 0;
+ // Count number of 0000 and FFFF blocks
+ for (int i=0; i<64; i+=16) {
+ int block = (int)(x >> i) & 0xFFFF;
+ if (block == 0) nb0++;
+ if (block == 0xFFFF) nb1++;
+ }
+ int pattern;
+ int op;
+ if(nb0 >= nb1) {
+ // More 0 blocks then F blocks, use movz
+ pattern = 0;
+ op = 0b110100101;
+ } else {
+ // More F blocks then 0 blocks, use movn
+ pattern = 0xFFFF;
+ op = 0b100100101;
+ }
+ int invert = pattern;
+ for (int i=0; i<4; i++) {
+ int block = (int)x & 0xFFFF;
+ x >>= 16;
+ if (block != pattern) {
+ enc.add4(arm.mov(op, i, block ^ invert, self));
+ op = 0b111100101;
+ invert = 0;
+ }
+ }
+ if (op != 0b111100101) {
+ // All blocks are the same, special case
+ enc.add4(arm.mov(op, 0, 0, self));
+ }
}
// Human-readable form appended to the SB. Things like the encoding,
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java
index cc0b2085..e08010f4 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java
@@ -20,8 +20,7 @@ public class UJmpARM extends CFGNode implements MachNode {
@Override public Node idealize() { throw Utils.TODO(); }
@Override public void encoding( Encoding enc ) {
enc.jump(this,uctrl());
- // TODO: unconditional jump
- int body = arm.b_cond(0b01010100, 0, arm.make_condition("<"));
+ int body = arm.b(0b01010100, 0);
enc.add4(body);
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java
index c6bb1973..bff08458 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java
@@ -252,7 +252,7 @@ public class arm extends Machine {
enc.add4(body);
}
- // encodes movk
+ // encodes movk, movn, and movz
public static int mov(int opcode, int shift, int imm16, int rd) {
return (opcode << 23) | (shift << 21) | (imm16 << 5) | rd;
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java
index bcffa544..cf330ed5 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java
@@ -19,9 +19,9 @@ public class UJmpRISC extends CFGNode implements MachNode {
@Override public Type compute() { throw Utils.TODO(); }
@Override public Node idealize() { throw Utils.TODO(); }
@Override public void encoding( Encoding enc ) {
+ // jal
enc.jump(this,uctrl());
- // TODO: Unconditional jump
- int body = riscv.b_type(0x63, 0, riscv.jumpop("<"), 0, 0, 0);
+ int body = riscv.j_type(0b0110111, 0, 0);
enc.add4(body);
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java
index 08239288..aa5de1aa 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java
@@ -131,7 +131,9 @@ public class riscv extends Machine {
public static int u_type(int opcode, int rd, int imm20) {
return (imm20 << 12) | (rd << 7) | opcode;
}
-
+ public static int j_type(int opcode, int rd, int imm20) {
+ return imm20 << 12 | rd << 7 | opcode;
+ }
public static int i_type(int opcode, int rd, int func3, int rs1, int imm12) {
assert opcode >= 0 && rd >=0 && func3 >=0 && rs1 >=0 && imm12 >= 0; // Zero-extend by caller
return (imm12 << 20) | (rs1 << 15) | (func3 << 12) | (rd << 7) | opcode;
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java
index d9836e00..6d9110f2 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java
@@ -36,14 +36,27 @@ public class IntX86 extends ConstantNode implements MachNode {
// Simply move the constant into a GPR
// Conditional encoding based on 64 or 32 bits
//REX.W + C7 /0 id MOV r/m64, imm32
- enc.add1(x86_64_v2.rex(0, dst, 0));
long imm = ((TypeInteger)_con).value();
- if( (int)imm == imm ) {
+ if (Integer.MIN_VALUE <= imm && imm < 0) {
+ // We need sign extension, so use imm32 into 64 bit register
+ // REX.W + C7 /0 id MOV r/m64, imm32
+ enc.add1(x86_64_v2.rex(0, dst, 0));
enc.add1(0xC7); // 32 bits encoding
enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0x00, dst));
enc.add4((int)imm);
+ } else if (0 <= imm && imm <= 0xFFFFFFFFL) {
+ // We want zero extension into 64 bit register
+ // so move 32 bit into 32 bit register which zeros
+ // the upper bits in the 64 bit register.
+ // B8+ rd id MOV r32, imm32
+ if (dst >= 8) enc.add1(0x41);
+ enc.add1(0xB8 + (dst & 0x07));
+ enc.add4((int)imm);
} else {
+ // Just write the full 64 bit constant
+ // REX.W + B8+ rd io MOV r64, imm64
+ enc.add1(x86_64_v2.rex(0, dst, 0));
enc.add1(0xB8 + (dst & 0x07));
enc.add8(imm); // 64 bits encoding
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java
index 4167962b..a80531b6 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java
@@ -33,15 +33,13 @@ public class TFPX86 extends ConstantNode implements MachNode {
return;
}
+ // lea to load function pointer address
+ // lea rax, [rip+disp32]
enc.relo(this,(TypeFunPtr)_con);
- // Simply move the constant into a GPR
- // Conditional encoding based on 64 or 32 bits
- //REX.W + C7 /0 id MOV r/m64, imm32
- enc.add1(x86_64_v2.rex(0, dst, 0));
- enc.add1(0xC7); // 32 bits encoding
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0x00, dst));
- //enc.add4((int)imm);
- throw Utils.TODO();
+ enc.add1(x86_64_v2.rex(dst, 0, 0));
+ enc.add1(0x8D); // opcode
+ enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.INDIRECT, dst, 0b101));
+ enc.add4(0);
}
// Human-readable form appended to the SB. Things like the encoding,