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) { ...@@ -255,11 +255,12 @@ void Assembler::rsc(Register rd, Register rn, Operand o, Condition cond) {
EmitType01(cond, o.type(), RSC, 0, rn, rd, o); 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) { void Assembler::tst(Register rn, Operand o, Condition cond) {
EmitType01(cond, o.type(), TST, 1, rn, R0, o); EmitType01(cond, o.type(), TST, 1, rn, R0, o);
} }
#endif
void Assembler::teq(Register rn, Operand o, Condition cond) { void Assembler::teq(Register rn, Operand o, Condition cond) {
EmitType01(cond, o.type(), TEQ, 1, rn, R0, o); EmitType01(cond, o.type(), TEQ, 1, rn, R0, o);
......
...@@ -480,7 +480,10 @@ class Assembler : public ValueObject { ...@@ -480,7 +480,10 @@ class Assembler : public ValueObject {
void rsc(Register rd, Register rn, Operand o, Condition cond = AL); 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); void tst(Register rn, Operand o, Condition cond = AL);
#endif
void teq(Register rn, Operand o, Condition cond = AL); void teq(Register rn, Operand o, Condition cond = AL);
......
...@@ -168,13 +168,13 @@ public: ...@@ -168,13 +168,13 @@ public:
void mov(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond); 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 movw(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond);
void movt(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, void orr(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
bool SetFlags, CondARM32::Cond Cond); bool SetFlags, CondARM32::Cond Cond);
...@@ -189,6 +189,8 @@ public: ...@@ -189,6 +189,8 @@ public:
void sub(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1, void sub(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
bool SetFlags, CondARM32::Cond Cond); 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, void udiv(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
CondARM32::Cond Cond); CondARM32::Cond Cond);
...@@ -216,10 +218,23 @@ private: ...@@ -216,10 +218,23 @@ private:
void emitType01(CondARM32::Cond Cond, IValueT Type, IValueT Opcode, void emitType01(CondARM32::Cond Cond, IValueT Type, IValueT Opcode,
bool SetCc, IValueT Rn, IValueT Rd, IValueT imm12); bool SetCc, IValueT Rn, IValueT Rd, IValueT imm12);
// Converts arguments to appropriate representation on a data operation, // List of possible checks to apply when calling emitType01() (below).
// and then calls emitType01 above. 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, 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); void emitType05(CondARM32::Cond COnd, int32_t Offset, bool Link);
...@@ -240,6 +255,12 @@ private: ...@@ -240,6 +255,12 @@ private:
void emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, IValueT Rn, void emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, IValueT Rn,
IValueT Rm, IValueT Rs, bool SetCc); 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); void emitBranch(Label *L, CondARM32::Cond, bool Link);
// Encodes the given Offset into the branch instruction Inst. // Encodes the given Offset into the branch instruction Inst.
......
...@@ -527,6 +527,14 @@ template <> void InstARM32Cmp::emitIAS(const Cfg *Func) const { ...@@ -527,6 +527,14 @@ template <> void InstARM32Cmp::emitIAS(const Cfg *Func) const {
emitUsingTextFixup(Func); 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, InstARM32Vcmp::InstARM32Vcmp(Cfg *Func, Variable *Src0, Variable *Src1,
CondARM32::Cond Predicate) CondARM32::Cond Predicate)
: InstARM32Pred(Func, InstARM32::Vcmp, 2, nullptr, Predicate) { : InstARM32Pred(Func, InstARM32::Vcmp, 2, nullptr, Predicate) {
......
...@@ -81,9 +81,15 @@ define internal void @mult_fwd_branches(i32 %a, i32 %b) { ...@@ -81,9 +81,15 @@ define internal void @mult_fwd_branches(i32 %a, i32 %b) {
; IASM-NEXT: .byte 0x50 ; IASM-NEXT: .byte 0x50
; IASM-NEXT: .byte 0xe1 ; 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
; IASM-NEXT: .byte 0x0 ; IASM-NEXT: .byte 0x0
......
...@@ -44,17 +44,24 @@ define internal i32 @SdivTwoRegs(i32 %a, i32 %b) { ...@@ -44,17 +44,24 @@ define internal i32 @SdivTwoRegs(i32 %a, i32 %b) {
; IASM-LABEL:SdivTwoRegs: ; IASM-LABEL:SdivTwoRegs:
; IASM-NEXT:.LSdivTwoRegs$__0: ; 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 0x0
; IASM-NEXT: .byte 0x0 ; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x1a ; IASM-NEXT: .byte 0x1a
; IASM-NEXT: .long 0xe7fedef0 ; IASM-NEXT: .long 0xe7fedef0
; IASM-NEXT:.LSdivTwoRegs$local$__0: ; IASM-NEXT:.LSdivTwoRegs$local$__0:
; IASM-NEXT: .byte 0x10 ; IASM-NEXT: .byte 0x10
; IASM-NEXT: .byte 0xf1 ; IASM-NEXT: .byte 0xf1
; IASM-NEXT: .byte 0x10 ; IASM-NEXT: .byte 0x10
; IASM-NEXT: .byte 0xe7 ; IASM-NEXT: .byte 0xe7
; IASM-NEXT: .byte 0x1e ; IASM-NEXT: .byte 0x1e
; IASM-NEXT: .byte 0xff ; IASM-NEXT: .byte 0xff
; IASM-NEXT: .byte 0x2f ; IASM-NEXT: .byte 0x2f
......
...@@ -44,17 +44,24 @@ define internal i32 @UdivTwoRegs(i32 %a, i32 %b) { ...@@ -44,17 +44,24 @@ define internal i32 @UdivTwoRegs(i32 %a, i32 %b) {
; IASM-LABEL:UdivTwoRegs: ; IASM-LABEL:UdivTwoRegs:
; IASM-NEXT:.LUdivTwoRegs$__0: ; 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 0x0
; IASM-NEXT: .byte 0x0 ; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x1a ; IASM-NEXT: .byte 0x1a
; IASM-NEXT: .long 0xe7fedef0 ; IASM-NEXT: .long 0xe7fedef0
; IASM-NEXT:.LUdivTwoRegs$local$__0: ; IASM-NEXT:.LUdivTwoRegs$local$__0:
; IASM-NEXT: .byte 0x10 ; IASM-NEXT: .byte 0x10
; IASM-NEXT: .byte 0xf1 ; IASM-NEXT: .byte 0xf1
; IASM-NEXT: .byte 0x30 ; IASM-NEXT: .byte 0x30
; IASM-NEXT: .byte 0xe7 ; IASM-NEXT: .byte 0xe7
; IASM-NEXT: .byte 0x1e ; IASM-NEXT: .byte 0x1e
; IASM-NEXT: .byte 0xff ; IASM-NEXT: .byte 0xff
; IASM-NEXT: .byte 0x2f ; 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