Commit 9c08bee8 by Karl Schimpf

Add orr (register) and orr (immediate) to ARM integrated assembler.

Also cleans up comments about handling a rotated imm8 value. BUG= https://code.google.com/p/nativeclient/issues/detail?id=4334 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1412923006 .
parent f0655b6c
...@@ -274,19 +274,18 @@ void Assembler::cmn(Register rn, Operand o, Condition cond) { ...@@ -274,19 +274,18 @@ void Assembler::cmn(Register rn, Operand o, Condition cond) {
EmitType01(cond, o.type(), CMN, 1, rn, R0, o); EmitType01(cond, o.type(), CMN, 1, rn, R0, o);
} }
#if 0
// Moved to ARM32::AssemberARM32::orr()
void Assembler::orr(Register rd, Register rn, Operand o, Condition cond) { void Assembler::orr(Register rd, Register rn, Operand o, Condition cond) {
EmitType01(cond, o.type(), ORR, 0, rn, rd, o); EmitType01(cond, o.type(), ORR, 0, rn, rd, o);
} }
// Moved to ARM32::AssemberARM32::orr()
void Assembler::orrs(Register rd, Register rn, Operand o, Condition cond) { void Assembler::orrs(Register rd, Register rn, Operand o, Condition cond) {
EmitType01(cond, o.type(), ORR, 1, rn, rd, o); EmitType01(cond, o.type(), ORR, 1, rn, rd, o);
} }
// Moved to AssemblerARM32::mov()
#if 0
// Moved to AssemblerARM32::mov(..FlexImm..)
// TODO(kschimpf) other forms of move. // TODO(kschimpf) other forms of move.
void Assembler::mov(Register rd, Operand o, Condition cond) { void Assembler::mov(Register rd, Operand o, Condition cond) {
EmitType01(cond, o.type(), MOV, 0, R0, rd, o); EmitType01(cond, o.type(), MOV, 0, R0, rd, o);
......
...@@ -481,11 +481,12 @@ class Assembler : public ValueObject { ...@@ -481,11 +481,12 @@ class Assembler : public ValueObject {
void cmn(Register rn, Operand o, Condition cond = AL); void cmn(Register rn, Operand o, Condition cond = AL);
#if 0
// Moved to ARM32::IceAssemblerARM32::orr().
void orr(Register rd, Register rn, Operand o, Condition cond = AL); void orr(Register rd, Register rn, Operand o, Condition cond = AL);
void orrs(Register rd, Register rn, Operand o, Condition cond = AL); void orrs(Register rd, Register rn, Operand o, Condition cond = AL);
#if 0 // Moved to ARM32::IceAssemblerARM32::mov()
// Moved to IceAssemblerARM32::mov()
void mov(Register rd, Operand o, Condition cond = AL); void mov(Register rd, Operand o, Condition cond = AL);
void movs(Register rd, Operand o, Condition cond = AL); void movs(Register rd, Operand o, Condition cond = AL);
#endif #endif
......
...@@ -442,7 +442,7 @@ void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, ...@@ -442,7 +442,7 @@ void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn,
// adc{s}<c> <Rd>, <Rn>, #<RotatedImm8> // adc{s}<c> <Rd>, <Rn>, #<RotatedImm8>
// //
// cccc0010101snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, // cccc0010101snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
// s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8. // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
// Conditions of rule violated. // Conditions of rule violated.
return setNeedsTextFixup(); return setNeedsTextFixup();
...@@ -490,7 +490,7 @@ void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn, ...@@ -490,7 +490,7 @@ void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn,
// add{s}<c> <Rd>, sp, #<RotatedImm8> // add{s}<c> <Rd>, sp, #<RotatedImm8>
// //
// cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
// s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8. // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
// Conditions of rule violated. // Conditions of rule violated.
return setNeedsTextFixup(); return setNeedsTextFixup();
...@@ -722,7 +722,7 @@ void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn, ...@@ -722,7 +722,7 @@ void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn,
// sbc{s}<c> <Rd>, <Rn>, #<RotatedImm8> // sbc{s}<c> <Rd>, <Rn>, #<RotatedImm8>
// //
// cccc0010110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, // cccc0010110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
// s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8. // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
// Conditions of rule violated. // Conditions of rule violated.
return setNeedsTextFixup(); return setNeedsTextFixup();
...@@ -768,6 +768,50 @@ void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, ...@@ -768,6 +768,50 @@ void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
} }
void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn,
const Operand *OpSrc1, bool SetFlags,
CondARM32::Cond Cond) {
IValueT Rd;
if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
return setNeedsTextFixup();
IValueT Rn;
if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
return setNeedsTextFixup();
constexpr IValueT Orr = B3 | B2; // i.e. 1100
IValueT Src1Value;
// TODO(kschimpf) Handle other possible decodings of orr.
switch (decodeOperand(OpSrc1, Src1Value)) {
default:
return setNeedsTextFixup();
case DecodedAsRegister: {
// ORR (register) - ARM Section A8.8.123, encoding A1:
// orr{s}<c> <Rd>, <Rn>, <Rm>
//
// cccc0001100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
// mmmm=Rm, iiiii=shift, tt=ShiftKind,, and s=SetFlags.
constexpr IValueT Shift = 0;
Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Shift);
if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
// Conditions of rule violated.
return setNeedsTextFixup();
emitType01(Cond, kInstTypeDataRegister, Orr, SetFlags, Rn, Rd, Src1Value);
return;
}
case DecodedAsRotatedImm8: {
// ORR (register) - ARM Section A8.8.123, encoding A1:
// orr{s}<c> <Rd>, <Rn>, #<RotatedImm8>
//
// cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
// s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
if (Rd == RegARM32::Encoded_Reg_pc && SetFlags)
// Conditions of rule violated.
return setNeedsTextFixup();
emitType01(Cond, kInstTypeDataImmediate, Orr, SetFlags, Rn, Rd, Src1Value);
return;
}
}
}
void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn, void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn,
const Operand *OpSrc1, bool SetFlags, const Operand *OpSrc1, bool SetFlags,
CondARM32::Cond Cond) { CondARM32::Cond Cond) {
...@@ -816,7 +860,8 @@ void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, ...@@ -816,7 +860,8 @@ void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn,
// //
// cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
// mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags. // mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags.
Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, 0); constexpr IValueT Shift = 0;
Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Shift);
if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
// Conditions of rule violated. // Conditions of rule violated.
return setNeedsTextFixup(); return setNeedsTextFixup();
...@@ -830,7 +875,7 @@ void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, ...@@ -830,7 +875,7 @@ void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn,
// sub{s}<c> sp, <Rn>, #<RotatedImm8> // sub{s}<c> sp, <Rn>, #<RotatedImm8>
// //
// cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
// s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
if (Rd == RegARM32::Encoded_Reg_pc) if (Rd == RegARM32::Encoded_Reg_pc)
// Conditions of rule violated. // Conditions of rule violated.
return setNeedsTextFixup(); return setNeedsTextFixup();
......
...@@ -161,6 +161,9 @@ public: ...@@ -161,6 +161,9 @@ public:
void movt(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond); void movt(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond);
void orr(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
bool SetFlags, CondARM32::Cond Cond);
void sbc(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1, void sbc(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
bool SetFlags, CondARM32::Cond Cond); bool SetFlags, CondARM32::Cond Cond);
......
...@@ -365,6 +365,13 @@ template <> void InstARM32And::emitIAS(const Cfg *Func) const { ...@@ -365,6 +365,13 @@ template <> void InstARM32And::emitIAS(const Cfg *Func) const {
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
} }
template <> void InstARM32Orr::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->orr(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
if (Asm->needsTextFixup())
emitUsingTextFixup(Func);
}
template <> void InstARM32Mul::emitIAS(const Cfg *Func) const { template <> void InstARM32Mul::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->mul(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); Asm->mul(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
......
; Show that we know how to translate or.
; NOTE: We use -O2 to get rid of memory stores.
; REQUIRES: allow_dump
; Compile using standalone assembler.
; RUN: %p2i --filetype=asm -i %s --target=arm32 --args -O2 \
; RUN: | FileCheck %s --check-prefix=ASM
; Show bytes in assembled standalone code.
; RUN: %p2i --filetype=asm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -O2 | FileCheck %s --check-prefix=DIS
; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 \
; RUN: | FileCheck %s --check-prefix=IASM
; Show bytes in assembled integrated code.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -O2 | FileCheck %s --check-prefix=DIS
define internal i32 @Or1WithR0(i32 %p) {
%v = or i32 %p, 1
ret i32 %v
}
; ASM-LABEL:Or1WithR0:
; ASM-NEXT:.LOr1WithR0$__0:
; ASM-NEXT: orr r0, r0, #1
; DIS-LABEL:00000000 <Or1WithR0>:
; DIS-NEXT: 0: e3800001
; IASM-LABEL:Or1WithR0:
; IASM-NEXT:.LOr1WithR0$__0:
; IASM-NEXT: .byte 0x1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x80
; IASM-NEXT: .byte 0xe3
define internal i32 @Or2Regs(i32 %p1, i32 %p2) {
%v = or i32 %p1, %p2
ret i32 %v
}
; ASM-LABEL:Or2Regs:
; ASM-NEXT:.LOr2Regs$__0:
; ASM-NEXT: orr r0, r0, r1
; DIS-LABEL:00000010 <Or2Regs>:
; DIS-NEXT: 10: e1800001
; IASM-LABEL:Or2Regs:
; IASM-NEXT:.LOr2Regs$__0:
; IASM-NEXT: .byte 0x1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x80
; IASM-NEXT: .byte 0xe1
define internal i64 @OrI64WithR0R1(i64 %p) {
%v = or i64 %p, 1
ret i64 %v
}
; ASM-LABEL:OrI64WithR0R1:
; ASM-NEXT:.LOrI64WithR0R1$__0:
; ASM-NEXT: orr r0, r0, #1
; ASM-NEXT: orr r1, r1, #0
; DIS-LABEL:00000020 <OrI64WithR0R1>:
; DIS-NEXT: 20: e3800001
; DIS-NEXT: 24: e3811000
; IASM-LABEL:OrI64WithR0R1:
; IASM-NEXT:.LOrI64WithR0R1$__0:
; IASM-NEXT: .byte 0x1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x80
; IASM-NEXT: .byte 0xe3
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x10
; IASM-NEXT: .byte 0x81
; IASM-NEXT: .byte 0xe3
define internal i64 @OrI64Regs(i64 %p1, i64 %p2) {
%v = or i64 %p1, %p2
ret i64 %v
}
; ASM-LABEL:OrI64Regs:
; ASM-NEXT:.LOrI64Regs$__0:
; ASM-NEXT: orr r0, r0, r2
; ASM-NEXT: orr r1, r1, r3
; DIS-LABEL:00000030 <OrI64Regs>:
; DIS-NEXT: 30: e1800002
; DIS-NEXT: 34: e1811003
; IASM-LABEL:OrI64Regs:
; IASM-NEXT:.LOrI64Regs$__0:
; IASM-NEXT: .byte 0x2
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x80
; IASM-NEXT: .byte 0xe1
; IASM-NEXT: .byte 0x3
; IASM-NEXT: .byte 0x10
; IASM-NEXT: .byte 0x81
; IASM-NEXT: .byte 0xe1
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