Commit b81b9015 by Karl Schimpf

Add TST(register, immediate) to ARM32 integrated assembler.

Also cleans up instructions that use emitType01 to share more common code. BUG= https://bugs.chromium.org/p/nativeclient/issues/detail?id=4334 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1413473005 .
parent 69e9290c
......@@ -255,11 +255,12 @@ void Assembler::rsc(Register rd, Register rn, Operand o, Condition cond) {
EmitType01(cond, o.type(), RSC, 0, rn, rd, o);
}
#if 0
// Moved to ARM32::AssemblerARM32::tst()
void Assembler::tst(Register rn, Operand o, Condition cond) {
EmitType01(cond, o.type(), TST, 1, rn, R0, o);
}
#endif
void Assembler::teq(Register rn, Operand o, Condition cond) {
EmitType01(cond, o.type(), TEQ, 1, rn, R0, o);
......
......@@ -480,7 +480,10 @@ class Assembler : public ValueObject {
void rsc(Register rd, Register rn, Operand o, Condition cond = AL);
#if 0
// Moved to ARM32::AssemblerARM32::tst();
void tst(Register rn, Operand o, Condition cond = AL);
#endif
void teq(Register rn, Operand o, Condition cond = AL);
......
......@@ -168,13 +168,13 @@ public:
void mov(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond);
void mul(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
bool SetFlags, CondARM32::Cond Cond);
void movw(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond);
void movt(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond);
void mul(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
bool SetFlags, CondARM32::Cond Cond);
void orr(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
bool SetFlags, CondARM32::Cond Cond);
......@@ -189,6 +189,8 @@ public:
void sub(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
bool SetFlags, CondARM32::Cond Cond);
void tst(const Operand *OpRn, const Operand *OpSrc1, CondARM32::Cond Cond);
void udiv(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
CondARM32::Cond Cond);
......@@ -216,10 +218,23 @@ private:
void emitType01(CondARM32::Cond Cond, IValueT Type, IValueT Opcode,
bool SetCc, IValueT Rn, IValueT Rd, IValueT imm12);
// Converts arguments to appropriate representation on a data operation,
// and then calls emitType01 above.
// List of possible checks to apply when calling emitType01() (below).
enum Type01Checks {
NoChecks,
RdIsPcAndSetFlags,
};
// Converts appropriate representation on a data operation, and then calls
// emitType01 above.
void emitType01(IValueT Opcode, const Operand *OpRd, const Operand *OpRn,
const Operand *OpSrc1, bool SetFlags, CondARM32::Cond Cond);
const Operand *OpSrc1, bool SetFlags, CondARM32::Cond Cond,
Type01Checks RuleChecks = RdIsPcAndSetFlags);
// Same as above, but the value for Rd and Rn have already been converted
// into instruction values.
void emitType01(IValueT Opcode, IValueT OpRd, IValueT OpRn,
const Operand *OpSrc1, bool SetFlags, CondARM32::Cond Cond,
Type01Checks RuleChecks = RdIsPcAndSetFlags);
void emitType05(CondARM32::Cond COnd, int32_t Offset, bool Link);
......@@ -240,6 +255,12 @@ private:
void emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, IValueT Rn,
IValueT Rm, IValueT Rs, bool SetCc);
// Pattern cccctttxxxxnnnn0000iiiiiiiiiiii where cccc=Cond, nnnn=Rn,
// ttt=Instruction type (derived from OpSrc1), iiiiiiiiiiii is derived from
// OpSrc1, and xxxx=Opcode.
void emitCompareOp(IValueT Opcode, const Operand *OpRn, const Operand *OpSrc1,
CondARM32::Cond Cond);
void emitBranch(Label *L, CondARM32::Cond, bool Link);
// Encodes the given Offset into the branch instruction Inst.
......
......@@ -527,6 +527,14 @@ template <> void InstARM32Cmp::emitIAS(const Cfg *Func) const {
emitUsingTextFixup(Func);
}
template <> void InstARM32Tst::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 2);
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->tst(getSrc(0), getSrc(1), getPredicate());
if (Asm->needsTextFixup())
emitUsingTextFixup(Func);
}
InstARM32Vcmp::InstARM32Vcmp(Cfg *Func, Variable *Src0, Variable *Src1,
CondARM32::Cond Predicate)
: InstARM32Pred(Func, InstARM32::Vcmp, 2, nullptr, Predicate) {
......
......@@ -81,9 +81,15 @@ define internal void @mult_fwd_branches(i32 %a, i32 %b) {
; IASM-NEXT: .byte 0x50
; IASM-NEXT: .byte 0xe1
; IASM-NEXT: movge r0, #0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0xa0
; IASM-NEXT: .byte 0xa3
; IASM-NEXT: movlt r0, #1
; IASM-NEXT: .byte 0x1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0xa0
; IASM-NEXT: .byte 0xb3
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
......
......@@ -44,17 +44,24 @@ define internal i32 @SdivTwoRegs(i32 %a, i32 %b) {
; IASM-LABEL:SdivTwoRegs:
; IASM-NEXT:.LSdivTwoRegs$__0:
; IASM-NEXT: tst r1, r1
; IASM-NEXT: .byte 0x1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x11
; IASM-NEXT: .byte 0xe1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x1a
; IASM-NEXT: .long 0xe7fedef0
; IASM-NEXT:.LSdivTwoRegs$local$__0:
; IASM-NEXT: .byte 0x10
; IASM-NEXT: .byte 0xf1
; IASM-NEXT: .byte 0x10
; IASM-NEXT: .byte 0xe7
; IASM-NEXT: .byte 0x1e
; IASM-NEXT: .byte 0xff
; IASM-NEXT: .byte 0x2f
......
......@@ -44,17 +44,24 @@ define internal i32 @UdivTwoRegs(i32 %a, i32 %b) {
; IASM-LABEL:UdivTwoRegs:
; IASM-NEXT:.LUdivTwoRegs$__0:
; IASM-NEXT: tst r1, r1
; IASM-NEXT: .byte 0x1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x11
; IASM-NEXT: .byte 0xe1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x1a
; IASM-NEXT: .long 0xe7fedef0
; IASM-NEXT:.LUdivTwoRegs$local$__0:
; IASM-NEXT: .byte 0x10
; IASM-NEXT: .byte 0xf1
; IASM-NEXT: .byte 0x30
; IASM-NEXT: .byte 0xe7
; IASM-NEXT: .byte 0x1e
; IASM-NEXT: .byte 0xff
; IASM-NEXT: .byte 0x2f
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment