Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Unified Diff: src/IceAssemblerARM32.cpp

Issue 1456783003: Add LSL (register, immediate) to ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix more nits. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceAssemblerARM32.cpp
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp
index a428664714748b7bacde22aa3e4a1ca2b1ad68fd..08ec1551f91caa5461da27a536a473675ec6126d 100644
--- a/src/IceAssemblerARM32.cpp
+++ b/src/IceAssemblerARM32.cpp
@@ -100,6 +100,7 @@ static constexpr IValueT kDivRnShift = 0;
// Type of instruction encoding (bits 25-27). See ARM section A5.1
static constexpr IValueT kInstTypeDataRegister = 0; // i.e. 000
+static constexpr IValueT kInstTypeDataRegShift = 0; // i.e. 000
static constexpr IValueT kInstTypeDataImmediate = 1; // i.e. 001
static constexpr IValueT kInstTypeMemImmediate = 2; // i.e. 010
static constexpr IValueT kInstTypeRegisterShift = 3; // i.e. 011
@@ -195,6 +196,8 @@ enum DecodedResult {
// kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if
// writeback to Rn.
DecodedAsShiftRotateImm5,
+ // i.e. 000000000000000000000iiiii0000000 iiii defines Imm5 value to shift.
+ DecodedAsShiftImm5,
// Value is 32bit integer constant.
DecodedAsConstI32
};
@@ -215,13 +218,23 @@ IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift,
return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm;
}
+// Encodes mmmmtt01ssss for data-processing (2nd) operands where mmmm=Rm,
+// ssss=Rs, and tt=Shift.
+IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift,
+ IValueT Rs) {
+ return (Rs << kRsShift) | (encodeShift(Shift) << kShiftShift) | B4 |
+ (Rm << kRmShift);
+}
+
DecodedResult decodeOperand(const Operand *Opnd, IValueT &Value) {
if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
if (Var->hasReg()) {
Value = Var->getRegNum();
return DecodedAsRegister;
}
- } else if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) {
+ return CantDecode;
+ }
+ if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) {
const IValueT Immed8 = FlexImm->getImm();
const IValueT Rotate = FlexImm->getRotateAmt();
if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits))))
@@ -233,6 +246,12 @@ DecodedResult decodeOperand(const Operand *Opnd, IValueT &Value) {
Value = Const->getValue();
return DecodedAsConstI32;
}
+ if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) {
+ const IValueT Immed5 = ShImm->getShAmtImm();
+ assert(Immed5 < (1 << kShiftImmBits));
+ Value = (Immed5 << kShiftImmShift);
+ return DecodedAsShiftImm5;
+ }
return CantDecode;
}
@@ -423,22 +442,33 @@ void AssemblerARM32::emitTextInst(const std::string &Text, SizeT InstSize) {
}
void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Type,
- IValueT Opcode, bool SetCc, IValueT Rn,
- IValueT Rd, IValueT Imm12) {
+ IValueT Opcode, bool SetFlags, IValueT Rn,
+ IValueT Rd, IValueT Imm12,
+ EmitChecks RuleChecks) {
+ switch (RuleChecks) {
+ case NoChecks:
+ break;
+ case RdIsPcAndSetFlags:
+ if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
Jim Stichnoth 2015/11/22 03:58:47 Maybe strip one level of parens?
Karl 2015/11/30 16:53:52 Done.
+ // Conditions of rule violated.
+ return setNeedsTextFixup();
+ break;
+ }
+
if (!isGPRRegisterDefined(Rd) || !isConditionDefined(Cond))
return setNeedsTextFixup();
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
(Type << kTypeShift) | (Opcode << kOpcodeShift) |
- (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) |
- (Rd << kRdShift) | Imm12;
+ (encodeBool(SetFlags) << kSShift) |
+ (Rn << kRnShift) | (Rd << kRdShift) | Imm12;
emitInst(Encoding);
}
void AssemblerARM32::emitType01(IValueT Opcode, const Operand *OpRd,
const Operand *OpRn, const Operand *OpSrc1,
bool SetFlags, CondARM32::Cond Cond,
- Type01Checks RuleChecks) {
+ EmitChecks RuleChecks) {
IValueT Rd;
if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
return setNeedsTextFixup();
@@ -450,7 +480,7 @@ void AssemblerARM32::emitType01(IValueT Opcode, const Operand *OpRd,
void AssemblerARM32::emitType01(IValueT Opcode, IValueT Rd, IValueT Rn,
const Operand *OpSrc1, bool SetFlags,
- CondARM32::Cond Cond, Type01Checks RuleChecks) {
+ CondARM32::Cond Cond, EmitChecks RuleChecks) {
switch (RuleChecks) {
case NoChecks:
break;
@@ -474,8 +504,8 @@ void AssemblerARM32::emitType01(IValueT Opcode, IValueT Rd, IValueT Rn,
// mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
constexpr IValueT Imm5 = 0;
Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5);
- emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd,
- Src1Value);
+ emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
+ RuleChecks);
return;
}
case DecodedAsConstI32: {
@@ -494,7 +524,7 @@ void AssemblerARM32::emitType01(IValueT Opcode, IValueT Rd, IValueT Rn,
// cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
// s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd,
- Src1Value);
+ Src1Value, RuleChecks);
return;
}
}
@@ -577,14 +607,15 @@ void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
}
void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
- IValueT Rn, IValueT Rm, IValueT Rs, bool SetCc) {
+ IValueT Rn, IValueT Rm, IValueT Rs,
+ bool SetFlags) {
if (!isGPRRegisterDefined(Rd) || !isGPRRegisterDefined(Rn) ||
!isGPRRegisterDefined(Rm) || !isGPRRegisterDefined(Rs) ||
!isConditionDefined(Cond))
return setNeedsTextFixup();
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) |
- (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) |
+ (encodeBool(SetFlags) << kSShift) | (Rn << kRnShift) |
(Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 |
(Rm << kRmShift);
emitInst(Encoding);
@@ -631,7 +662,7 @@ void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn,
// cccc0010101snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
// s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
constexpr IValueT Adc = B2 | B0; // 0101
- emitType01(Adc, OpRd, OpRn, OpSrc1, SetFlags, Cond);
+ emitType01(Adc, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
}
void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn,
@@ -653,7 +684,7 @@ void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn,
// cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
// s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
constexpr IValueT Add = B2; // 0100
- emitType01(Add, OpRd, OpRn, OpSrc1, SetFlags, Cond);
+ emitType01(Add, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
}
void AssemblerARM32::and_(const Operand *OpRd, const Operand *OpRn,
@@ -671,7 +702,7 @@ void AssemblerARM32::and_(const Operand *OpRd, const Operand *OpRn,
// cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
// s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
constexpr IValueT And = 0; // 0000
- emitType01(And, OpRd, OpRn, OpSrc1, SetFlags, Cond);
+ emitType01(And, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
}
void AssemblerARM32::b(Label *L, CondARM32::Cond Cond) {
@@ -704,7 +735,7 @@ void AssemblerARM32::bic(const Operand *OpRd, const Operand *OpRn,
// cccc0011110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rn, nnnn=Rn,
// s=SetFlags, and iiiiiiiiiiii=Src1Value defining RotatedImm8.
IValueT Opcode = B3 | B2 | B1; // i.e. 1110
- emitType01(Opcode, OpRd, OpRn, OpSrc1, SetFlags, Cond);
+ emitType01(Opcode, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
}
void AssemblerARM32::bl(const ConstantRelocatable *Target) {
@@ -785,7 +816,7 @@ void AssemblerARM32::eor(const Operand *OpRd, const Operand *OpRn,
// cccc0010001snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
// s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
constexpr IValueT Eor = B0; // 0001
- emitType01(Eor, OpRd, OpRn, OpSrc1, SetFlags, Cond);
+ emitType01(Eor, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
}
void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
@@ -868,6 +899,51 @@ void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
}
}
+void AssemblerARM32::lsl(const Operand *OpRd, const Operand *OpRm,
+ const Operand *OpSrc1, bool SetFlags,
+ CondARM32::Cond Cond) {
+ constexpr IValueT Lsl = B3 | B2 | B0; // 1101
+ constexpr IValueT Rn = 0; // Rn field is not used.
+ IValueT Rd;
+ if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
+ return setNeedsTextFixup();
+ IValueT Rm;
+ if (decodeOperand(OpRm, Rm) != DecodedAsRegister)
+ return setNeedsTextFixup();
+ IValueT Value;
+ switch (decodeOperand(OpSrc1, Value)) {
+ default:
+ return setNeedsTextFixup();
+ case DecodedAsShiftImm5: {
+ // LSL (immediate) - ARM section A8.8.94, encoding A1:
+ // lsl{s}<c> <Rd>, <Rm>, #imm5
+ //
+ // cccc0001101s0000ddddiiiii000mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
+ // iiiii=imm5, and mmmm=Rm.
+ Value = Value | (Rm << kRmShift);
+ emitType01(Cond, kInstTypeDataRegShift, Lsl, SetFlags, Rn, Rd, Value,
+ RdIsPcAndSetFlags);
+ return;
+ }
+ case DecodedAsRegister: {
+ // LSL (register) - ARM section A8.8.95, encoding A1:
+ // lsl{S}<c> <Rd>, <Rm>, <Rs>
+ //
+ // cccc0001101s0000ddddssss0001mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
+ // mmmm=Rm, and ssss=Rs.
+ IValueT Rs;
+ if (decodeOperand(OpSrc1, Rs) != DecodedAsRegister)
+ return setNeedsTextFixup();
+ if ((Rd == RegARM32::Encoded_Reg_pc) || (Rm == RegARM32::Encoded_Reg_pc) ||
+ (Rs == RegARM32::Encoded_Reg_pc))
+ setNeedsTextFixup();
+ emitType01(Cond, kInstTypeDataRegShift, Lsl, SetFlags, Rn, Rd,
+ encodeShiftRotateReg(Rm, OperandARM32::kNoShift, Rs), NoChecks);
+ return;
+ }
+ }
+}
+
void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
CondARM32::Cond Cond) {
// MOV (register) - ARM section A8.8.104, encoding A1:
@@ -888,7 +964,7 @@ void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
constexpr bool SetFlags = false;
constexpr IValueT Rn = 0;
constexpr IValueT Mov = B3 | B2 | B0; // 1101.
- emitType01(Mov, Rd, Rn, OpSrc, SetFlags, Cond);
+ emitType01(Mov, Rd, Rn, OpSrc, SetFlags, Cond, RdIsPcAndSetFlags);
}
void AssemblerARM32::emitMovw(IValueT Opcode, IValueT Rd, IValueT Imm16,
@@ -986,7 +1062,7 @@ void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn,
// cccc0010110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
// s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
constexpr IValueT Sbc = B2 | B1; // 0110
- emitType01(Sbc, OpRd, OpRn, OpSrc1, SetFlags, Cond);
+ emitType01(Sbc, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
}
void AssemblerARM32::sdiv(const Operand *OpRd, const Operand *OpRn,
@@ -1064,7 +1140,7 @@ void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn,
// cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
// s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
constexpr IValueT Orr = B3 | B2; // i.e. 1100
- emitType01(Orr, OpRd, OpRn, OpSrc1, SetFlags, Cond);
+ emitType01(Orr, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
}
void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) {
@@ -1218,7 +1294,7 @@ void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn,
// cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
// s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8
constexpr IValueT Sub = B1; // 0010
- emitType01(Sub, OpRd, OpRn, OpSrc1, SetFlags, Cond);
+ emitType01(Sub, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
}
void AssemblerARM32::tst(const Operand *OpRn, const Operand *OpSrc1,
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.cpp » ('j') | tests_lit/assembler/arm32/lsl.ll » ('J')

Powered by Google App Engine
This is Rietveld 408576698