aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2010-10-08 21:45:55 +0000
committerJim Grosbach <grosbach@apple.com>2010-10-08 21:45:55 +0000
commit56ac907c57fcfddfd650238f03c856a9d55987e5 (patch)
tree64533bf920c7ee91304a627614d1e74e089cb83c
parent6313944845265dbf38e68046a047d78162f5b89e (diff)
downloadexternal_llvm-56ac907c57fcfddfd650238f03c856a9d55987e5.tar.gz
external_llvm-56ac907c57fcfddfd650238f03c856a9d55987e5.tar.bz2
external_llvm-56ac907c57fcfddfd650238f03c856a9d55987e5.zip
Implement a few more binary encoding bits. Still very early stage proof-of-
concept level stuff at this point, but it is generally working for those instructions that know how to map the operands. This patch fills in the register operands for add/sub/or/etc instructions and adds the conditional execution predicate encoding. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116112 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td30
-rw-r--r--lib/Target/ARM/ARMMCCodeEmitter.cpp19
-rw-r--r--test/MC/ARM/simple-encoding.ll10
3 files changed, 58 insertions, 1 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 95bc1d9025..41c9cca90f 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -481,9 +481,17 @@ multiclass AsI1_bin_irs<bits<4> opcod, string opc,
def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
iir, opc, "\t$dst, $a, $b",
[(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
+ bits<4> Rd;
+ bits<4> Rn;
+ bits<4> Rm;
+ bits<4> Cond;
let Inst{11-4} = 0b00000000;
let Inst{25} = 0;
let isCommutable = Commutable;
+ let Inst{3-0} = Rm;
+ let Inst{15-12} = Rd;
+ let Inst{19-16} = Rn;
+ let Inst{31-28} = Cond;
}
def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
iis, opc, "\t$dst, $a, $b",
@@ -907,20 +915,24 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
"bx", "\tlr", [(ARMretflag)]>,
Requires<[IsARM, HasV4T]> {
+ bits<4> Cond;
let Inst{3-0} = 0b1110;
let Inst{7-4} = 0b0001;
let Inst{19-8} = 0b111111111111;
let Inst{27-20} = 0b00010010;
+ let Inst{31-28} = Cond;
}
// ARMV4 only
def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
"mov", "\tpc, lr", [(ARMretflag)]>,
Requires<[IsARM, NoV4T]> {
+ bits<4> Cond;
let Inst{11-0} = 0b000000001110;
let Inst{15-12} = 0b1111;
let Inst{19-16} = 0b0000;
let Inst{27-20} = 0b00011010;
+ let Inst{31-28} = Cond;
}
}
@@ -930,21 +942,27 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
[(brind GPR:$dst)]>,
Requires<[IsARM, HasV4T]> {
+ bits<4> Rm;
+
let Inst{7-4} = 0b0001;
let Inst{19-8} = 0b111111111111;
let Inst{27-20} = 0b00010010;
let Inst{31-28} = 0b1110;
+ let Inst{3-0} = Rm;
}
// ARMV4 only
def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
[(brind GPR:$dst)]>,
Requires<[IsARM, NoV4T]> {
+ bits<4> Rm;
+
let Inst{11-4} = 0b00000000;
let Inst{15-12} = 0b1111;
let Inst{19-16} = 0b0000;
let Inst{27-20} = 0b00011010;
let Inst{31-28} = 0b1110;
+ let Inst{3-0} = Rm;
}
}
@@ -981,9 +999,11 @@ let isCall = 1,
IIC_Br, "blx\t$func",
[(ARMcall GPR:$func)]>,
Requires<[IsARM, HasV5T, IsNotDarwin]> {
+ bits<4> Rm;
let Inst{7-4} = 0b0011;
let Inst{19-8} = 0b111111111111;
let Inst{27-20} = 0b00010010;
+ let Inst{3-0} = Rm;
}
// ARMv4T
@@ -1493,16 +1513,26 @@ def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
let neverHasSideEffects = 1 in
def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
"mov", "\t$dst, $src", []>, UnaryDP {
+ bits<4> Rd;
+ bits<4> Rm;
+
let Inst{11-4} = 0b00000000;
let Inst{25} = 0;
+ let Inst{3-0} = Rm;
+ let Inst{15-12} = Rd;
}
// A version for the smaller set of tail call registers.
let neverHasSideEffects = 1 in
def MOVr_TC : AsI1<0b1101, (outs tcGPR:$dst), (ins tcGPR:$src), DPFrm,
IIC_iMOVr, "mov", "\t$dst, $src", []>, UnaryDP {
+ bits<4> Rd;
+ bits<4> Rm;
+
let Inst{11-4} = 0b00000000;
let Inst{25} = 0;
+ let Inst{3-0} = Rm;
+ let Inst{15-12} = Rd;
}
def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp
index 1f45eb9405..fce1f3914d 100644
--- a/lib/Target/ARM/ARMMCCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp
@@ -106,6 +106,25 @@ EmitImmediate(const MCOperand &DispOp, unsigned Size, MCFixupKind FixupKind,
assert(0 && "ARMMCCodeEmitter::EmitImmediate() not yet implemented.");
}
+/// getMachineOpValue - Return binary encoding of operand. If the machine
+/// operand requires relocation, record the relocation and return zero.
+unsigned ARMMCCodeEmitter::getMachineOpValue(const MCInst &MI,
+ const MCOperand &MO) const {
+ if (MO.isReg())
+ // FIXME: Should shifted register stuff be handled as part of this? Maybe.
+ return getARMRegisterNumbering(MO.getReg());
+ else if (MO.isImm())
+ // FIXME: This is insufficient. Shifted immediates and all that... (blech).
+ return static_cast<unsigned>(MO.getImm());
+ else {
+#ifndef NDEBUG
+ errs() << MO;
+#endif
+ llvm_unreachable(0);
+ }
+ return 0;
+}
+
void ARMMCCodeEmitter::
EncodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const {
diff --git a/test/MC/ARM/simple-encoding.ll b/test/MC/ARM/simple-encoding.ll
index af7cf71ade..2da4e74c89 100644
--- a/test/MC/ARM/simple-encoding.ll
+++ b/test/MC/ARM/simple-encoding.ll
@@ -9,10 +9,18 @@ define i32 @foo(i32 %a, i32 %b) nounwind ssp {
entry:
; CHECK: foo
; CHECK: 0xf0,0x00,0xf0,0x07
-; CHECK: 0x1e,0xff,0x2f,0x01
+; CHECK: 0x1e,0xff,0x2f,0xe1
tail call void @llvm.trap()
ret i32 undef
}
+define i32 @f2(i32 %a, i32 %b) nounwind readnone ssp {
+entry:
+; CHECK: f2
+; CHECK: 0x00,0x00,0x81,0xe0
+; CHECK: 0x1e,0xff,0x2f,0xe1
+ %add = add nsw i32 %b, %a
+ ret i32 %add
+}
declare void @llvm.trap() nounwind