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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1411873002: emit add/sub registers instructions in integrated ARM assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 5 years, 2 months 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 unified diff | Download patch
« no previous file with comments | « src/DartARM32/assembler_arm.h ('k') | tests_lit/assembler/arm32/add.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===//
2 // 2 //
3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
4 // for details. All rights reserved. Use of this source code is governed by a 4 // for details. All rights reserved. Use of this source code is governed by a
5 // BSD-style license that can be found in the LICENSE file. 5 // BSD-style license that can be found in the LICENSE file.
6 // 6 //
7 // Modified by the Subzero authors. 7 // Modified by the Subzero authors.
8 // 8 //
9 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
10 // 10 //
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 static constexpr uint32_t kRnShift = 16; 55 static constexpr uint32_t kRnShift = 16;
56 static constexpr uint32_t kSShift = 20; 56 static constexpr uint32_t kSShift = 20;
57 static constexpr uint32_t kTypeShift = 25; 57 static constexpr uint32_t kTypeShift = 25;
58 58
59 // Immediate instruction fields encoding. 59 // Immediate instruction fields encoding.
60 static constexpr uint32_t kImmed8Bits = 8; 60 static constexpr uint32_t kImmed8Bits = 8;
61 static constexpr uint32_t kImmed8Shift = 0; 61 static constexpr uint32_t kImmed8Shift = 0;
62 static constexpr uint32_t kRotateBits = 4; 62 static constexpr uint32_t kRotateBits = 4;
63 static constexpr uint32_t kRotateShift = 8; 63 static constexpr uint32_t kRotateShift = 8;
64 64
65 // Shift instruction register fields encodings.
66 static constexpr uint32_t kShiftImmShift = 7;
67 static constexpr uint32_t kShiftImmBits = 5;
68 static constexpr uint32_t kShiftShift = 5;
69
65 static constexpr uint32_t kImmed12Bits = 12; 70 static constexpr uint32_t kImmed12Bits = 12;
66 static constexpr uint32_t kImm12Shift = 0; 71 static constexpr uint32_t kImm12Shift = 0;
67 72
68 inline uint32_t encodeBool(bool b) { return b ? 1 : 0; } 73 inline uint32_t encodeBool(bool b) { return b ? 1 : 0; }
69 74
70 inline uint32_t encodeGPRRegister(RegARM32::GPRRegister Rn) { 75 inline uint32_t encodeGPRRegister(RegARM32::GPRRegister Rn) {
71 return static_cast<uint32_t>(Rn); 76 return static_cast<uint32_t>(Rn);
72 } 77 }
73 78
74 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) { 79 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) {
75 return R != RegARM32::Encoded_Not_GPR; 80 return R != RegARM32::Encoded_Not_GPR;
76 } 81 }
77 82
78 inline bool isGPRRegisterDefined(uint32_t R) { 83 inline bool isGPRRegisterDefined(uint32_t R) {
79 return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR); 84 return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR);
80 } 85 }
81 86
82 inline bool isConditionDefined(CondARM32::Cond Cond) { 87 inline bool isConditionDefined(CondARM32::Cond Cond) {
83 return Cond != CondARM32::kNone; 88 return Cond != CondARM32::kNone;
84 } 89 }
85 90
86 inline uint32_t encodeCondition(CondARM32::Cond Cond) { 91 inline uint32_t encodeCondition(CondARM32::Cond Cond) {
87 return static_cast<uint32_t>(Cond); 92 return static_cast<uint32_t>(Cond);
88 } 93 }
89 94
95 uint32_t encodeShift(OperandARM32::ShiftKind Shift) {
96 // Follows encoding in ARM section A8.4.1 "Constant shifts".
97 switch (Shift) {
98 case OperandARM32::kNoShift:
99 case OperandARM32::LSL:
100 return 0; // 0b00
101 case OperandARM32::LSR:
102 return 1; // 0b01
103 case OperandARM32::ASR:
104 return 2; // 0b10
105 case OperandARM32::ROR:
106 case OperandARM32::RRX:
107 return 3; // 0b11
108 }
109 }
110
90 // Returns the bits in the corresponding masked value. 111 // Returns the bits in the corresponding masked value.
91 inline uint32_t mask(uint32_t Value, uint32_t Shift, uint32_t Bits) { 112 inline uint32_t mask(uint32_t Value, uint32_t Shift, uint32_t Bits) {
92 return (Value >> Shift) & ((1 << Bits) - 1); 113 return (Value >> Shift) & ((1 << Bits) - 1);
93 } 114 }
94 115
95 // Extract out a Bit in Value. 116 // Extract out a Bit in Value.
96 inline bool isBitSet(uint32_t Bit, uint32_t Value) { 117 inline bool isBitSet(uint32_t Bit, uint32_t Value) {
97 return (Value & Bit) == Bit; 118 return (Value & Bit) == Bit;
98 } 119 }
99 120
(...skipping 11 matching lines...) Expand all
111 DecodedAsRegister, 132 DecodedAsRegister,
112 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8 133 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8
113 // value. 134 // value.
114 DecodedAsRotatedImm8, 135 DecodedAsRotatedImm8,
115 // i.e. 0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn, 136 // i.e. 0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn,
116 // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to 137 // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to
117 // Rn should be used, and iiiiiiiiiiii is the offset. 138 // Rn should be used, and iiiiiiiiiiii is the offset.
118 DecodedAsImmRegOffset 139 DecodedAsImmRegOffset
119 }; 140 };
120 141
142 // Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5,
143 // tt=Shift, and mmmm=Rm.
144 uint32_t encodeShiftRotateImm5(uint32_t Rm, OperandARM32::ShiftKind Shift,
145 uint32_t imm5) {
146 (void)kShiftImmBits;
147 assert(imm5 < (1 << kShiftImmBits));
148 return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm;
149 }
150
121 DecodedResult decodeOperand(const Operand *Opnd, uint32_t &Value) { 151 DecodedResult decodeOperand(const Operand *Opnd, uint32_t &Value) {
122 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { 152 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
123 if (Var->hasReg()) { 153 if (Var->hasReg()) {
124 Value = Var->getRegNum(); 154 Value = Var->getRegNum();
125 return DecodedAsRegister; 155 return DecodedAsRegister;
126 } 156 }
127 } else if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) { 157 } else if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) {
128 const uint32_t Immed8 = FlexImm->getImm(); 158 const uint32_t Immed8 = FlexImm->getImm();
129 const uint32_t Rotate = FlexImm->getRotateAmt(); 159 const uint32_t Rotate = FlexImm->getRotateAmt();
130 assert((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits))); 160 assert((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits)));
131 // TODO(kschimpf): Remove void casts when MINIMAL build allows. 161 // TODO(kschimpf): Remove void casts when MINIMAL build allows.
132 (void) kRotateBits; 162 (void)kRotateBits;
133 (void) kImmed8Bits; 163 (void)kImmed8Bits;
134 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); 164 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift);
135 return DecodedAsRotatedImm8; 165 return DecodedAsRotatedImm8;
136 } 166 }
137 return CantDecode; 167 return CantDecode;
138 } 168 }
139 169
140 uint32_t decodeImmRegOffset(RegARM32::GPRRegister Reg, int32_t Offset, 170 uint32_t decodeImmRegOffset(RegARM32::GPRRegister Reg, int32_t Offset,
141 OperandARM32Mem::AddrMode Mode) { 171 OperandARM32Mem::AddrMode Mode) {
142 uint32_t Value = Mode | (encodeGPRRegister(Reg) << kRnShift); 172 uint32_t Value = Mode | (encodeGPRRegister(Reg) << kRnShift);
143 if (Offset < 0) { 173 if (Offset < 0) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 } 229 }
200 // TODO(kschimpf) Decide if we have near jumps. 230 // TODO(kschimpf) Decide if we have near jumps.
201 label->bindTo(bound); 231 label->bindTo(bound);
202 } 232 }
203 233
204 void ARM32::AssemblerARM32::emitType01(CondARM32::Cond Cond, uint32_t Type, 234 void ARM32::AssemblerARM32::emitType01(CondARM32::Cond Cond, uint32_t Type,
205 uint32_t Opcode, bool SetCc, uint32_t Rn, 235 uint32_t Opcode, bool SetCc, uint32_t Rn,
206 uint32_t Rd, uint32_t Imm12) { 236 uint32_t Rd, uint32_t Imm12) {
207 assert(isGPRRegisterDefined(Rd)); 237 assert(isGPRRegisterDefined(Rd));
208 // TODO(kschimpf): Remove void cast when MINIMAL build allows. 238 // TODO(kschimpf): Remove void cast when MINIMAL build allows.
209 (void) isGPRRegisterDefined(Rd); 239 (void)isGPRRegisterDefined(Rd);
210 assert(Cond != CondARM32::kNone); 240 assert(Cond != CondARM32::kNone);
211 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 241 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
212 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | 242 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) |
213 (Type << kTypeShift) | (Opcode << kOpcodeShift) | 243 (Type << kTypeShift) | (Opcode << kOpcodeShift) |
214 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | 244 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) |
215 (Rd << kRdShift) | Imm12; 245 (Rd << kRdShift) | Imm12;
216 emitInst(Encoding); 246 emitInst(Encoding);
217 } 247 }
218 248
219 void ARM32::AssemblerARM32::emitMemOp(CondARM32::Cond Cond, uint32_t InstType, 249 void ARM32::AssemblerARM32::emitMemOp(CondARM32::Cond Cond, uint32_t InstType,
(...skipping 12 matching lines...) Expand all
232 const Operand *OpSrc1, bool SetFlags, 262 const Operand *OpSrc1, bool SetFlags,
233 CondARM32::Cond Cond) { 263 CondARM32::Cond Cond) {
234 // Note: Loop is used so that we can short circuit using break; 264 // Note: Loop is used so that we can short circuit using break;
235 do { 265 do {
236 uint32_t Rd; 266 uint32_t Rd;
237 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 267 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
238 break; 268 break;
239 uint32_t Rn; 269 uint32_t Rn;
240 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 270 if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
241 break; 271 break;
272 constexpr uint32_t Add = B2; // 0100
242 uint32_t Src1Value; 273 uint32_t Src1Value;
243 // TODO(kschimpf) Other possible decodings of add. 274 // TODO(kschimpf) Other possible decodings of add.
244 if (decodeOperand(OpSrc1, Src1Value) == DecodedAsRotatedImm8) { 275 switch (decodeOperand(OpSrc1, Src1Value)) {
245 // ADD (Immediate): See ARM section A8.8.5, rule A1. 276 default:
246 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 277 break;
247 // s=SetFlags and iiiiiiiiiiii=Src1Value 278 case DecodedAsRegister: {
248 if (!isConditionDefined(Cond) || (Rd == RegARM32::Reg_pc && SetFlags) || 279 // ADD (register) - ARM section A8.8.7, encoding A1:
249 (Rn == RegARM32::Reg_lr) || (Rn == RegARM32::Reg_pc && SetFlags)) 280 // add{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
281 // ADD (Sp plus register) - ARM section A8.8.11, encoding A1:
282 // add{s}<c> sp, <Rn>, <Rm>{, <shiff>}
283 //
284 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
285 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags
286 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, 0);
287 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
250 // Conditions of rule violated. 288 // Conditions of rule violated.
251 break; 289 break;
252 constexpr uint32_t Add = B2; // 0100 290 constexpr uint32_t InstTypeRegister = 0;
253 constexpr uint32_t InstType = 1; 291 emitType01(Cond, InstTypeRegister, Add, SetFlags, Rn, Rd, Src1Value);
254 emitType01(Cond, InstType, Add, SetFlags, Rn, Rd, Src1Value);
255 return; 292 return;
256 } 293 }
294 case DecodedAsRotatedImm8: {
295 // ADD (Immediate) - ARM section A8.8.5, encoding A1:
296 // add{s}<c> <Rd>, <Rn>, #<RotatedImm8>
297 // ADD (SP plus immediate) - ARM section A8.8.9, encoding A1.
298 // add{s}<c> <Rd>, sp, #<RotatedImm8>
299 //
300 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
301 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8.
302 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
303 // Conditions of rule violated.
304 break;
305 constexpr uint32_t InstTypeImmediate = 1;
306 emitType01(Cond, InstTypeImmediate, Add, SetFlags, Rn, Rd, Src1Value);
307 return;
308 }
309 }
257 } while (0); 310 } while (0);
258 UnimplementedError(Ctx->getFlags()); 311 UnimplementedError(Ctx->getFlags());
259 } 312 }
260 313
261 void ARM32::AssemblerARM32::bkpt(uint16_t imm16) { 314 void ARM32::AssemblerARM32::bkpt(uint16_t Imm16) {
315 // BKPT - ARM section A*.8.24 - encoding A1:
316 // bkpt #<Imm16>
317 //
318 // cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and iiiiiiiiiiiiiiii=Imm16
262 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 319 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
263 const uint32_t Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 | 320 const uint32_t Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 |
264 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf); 321 ((Imm16 >> 4) << 8) | B6 | B5 | B4 | (Imm16 & 0xf);
265 emitInst(Encoding); 322 emitInst(Encoding);
266 } 323 }
267 324
268 void ARM32::AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) { 325 void ARM32::AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) {
326 // BX - ARM section A8.8.27, encoding A1:
327 // bx<c> <Rm>
328 //
269 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond. 329 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond.
270 // (ARM section A8.8.27, encoding A1).
271 assert(isGPRRegisterDefined(Rm)); 330 assert(isGPRRegisterDefined(Rm));
272 // TODO(kschimpf): Remove void cast when MINIMAL build allows. 331 // TODO(kschimpf): Remove void cast when MINIMAL build allows.
273 (void) isGPRRegisterDefined(Rm); 332 (void)isGPRRegisterDefined(Rm);
274 assert(isConditionDefined(Cond)); 333 assert(isConditionDefined(Cond));
334 (void)isConditionDefined(Cond);
275 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 335 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
276 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | 336 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 |
277 B21 | (0xfff << 8) | B4 | 337 B21 | (0xfff << 8) | B4 |
278 (encodeGPRRegister(Rm) << kRmShift); 338 (encodeGPRRegister(Rm) << kRmShift);
279 emitInst(Encoding); 339 emitInst(Encoding);
280 } 340 }
281 341
282 void ARM32::AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, 342 void ARM32::AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
283 CondARM32::Cond Cond) { 343 CondARM32::Cond Cond) {
284 // Note: Loop is used so that we can short ciruit using break; 344 // Note: Loop is used so that we can short ciruit using break;
285 do { 345 do {
286 uint32_t Rt; 346 uint32_t Rt;
287 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 347 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
288 break; 348 break;
289 uint32_t Address; 349 uint32_t Address;
290 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) 350 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset)
291 break; 351 break;
292 // cccc010pu0w1nnnnttttiiiiiiiiiiii (ARM section A8.8.63, encoding A1; and 352 // LDR (immediate) - ARM section A8.8.63, encoding A1:
293 // section A8.6.68, encoding A1). 353 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
354 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
355 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
356 // LDRB (immediate) - ARM section A8.8.68, encoding A1:
357 // ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
358 // ldrb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
359 // ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
360 //
361 // cccc010pubw1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
362 // iiiiiiiiiiii=imm12, b=1 if STRB, u=1 if +.
294 constexpr uint32_t InstType = B1; // 010 363 constexpr uint32_t InstType = B1; // 010
295 constexpr bool IsLoad = true; 364 constexpr bool IsLoad = true;
296 const Type Ty = OpRt->getType(); 365 const Type Ty = OpRt->getType();
297 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand? 366 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand?
298 break; 367 break;
299 const bool IsByte = typeWidthInBytes(Ty) == 1; 368 const bool IsByte = typeWidthInBytes(Ty) == 1;
300 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) || 369 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) ||
301 (!IsByte && !isBitSet(P, Address) && isBitSet(W, Address)) || 370 (!isBitSet(P, Address) && isBitSet(W, Address)) ||
302 ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && 371 (!IsByte &&
372 (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) &&
303 !isBitSet(P, Address) && 373 !isBitSet(P, Address) &&
304 isBitSet(U, Address) & !isBitSet(W, Address) && 374 isBitSet(U, Address) & !isBitSet(W, Address) &&
305 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))) 375 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)))
306 break; 376 break;
307 emitMemOp(Cond, InstType, IsLoad, IsByte, Rt, Address); 377 emitMemOp(Cond, InstType, IsLoad, IsByte, Rt, Address);
308 return; 378 return;
309 } while (0); 379 } while (0);
310 UnimplementedError(Ctx->getFlags()); 380 UnimplementedError(Ctx->getFlags());
311 } 381 }
312 382
313 void ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, 383 void ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
314 CondARM32::Cond Cond) { 384 CondARM32::Cond Cond) {
315 // Note: Loop is used so that we can short ciruit using break; 385 // Note: Loop is used so that we can short ciruit using break;
316 do { 386 do {
317 uint32_t Rd; 387 uint32_t Rd;
318 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 388 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
319 break; 389 break;
320 uint32_t Src; 390 uint32_t Src;
321 // TODO(kschimpf) Handle other forms of mov. 391 // TODO(kschimpf) Handle other forms of mov.
322 if (decodeOperand(OpSrc, Src) == DecodedAsRotatedImm8) { 392 if (decodeOperand(OpSrc, Src) == DecodedAsRotatedImm8) {
323 // cccc0011101s0000ddddiiiiiiiiiiii (ARM section A8.8.102, encoding A1) 393 // MOV (immediate) - ARM section A8.8.102, encoding A1:
324 // Note: We don't use movs in this assembler. 394 // mov{S}<c> <Rd>, #<RotatedImm8>
395 //
396 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd,
397 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this
398 // assembler.
325 constexpr bool SetFlags = false; 399 constexpr bool SetFlags = false;
326 if (!isConditionDefined(Cond) || (Rd == RegARM32::Reg_pc && SetFlags)) 400 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
327 // Conditions of rule violated. 401 // Conditions of rule violated.
328 break; 402 break;
329 constexpr uint32_t Rn = 0; 403 constexpr uint32_t Rn = 0;
330 constexpr uint32_t Mov = B3 | B2 | B0; // 1101. 404 constexpr uint32_t Mov = B3 | B2 | B0; // 1101.
331 constexpr uint32_t InstType = 1; 405 constexpr uint32_t InstType = 1;
332 emitType01(Cond, InstType, Mov, SetFlags, Rn, Rd, Src); 406 emitType01(Cond, InstType, Mov, SetFlags, Rn, Rd, Src);
333 return; 407 return;
334 } 408 }
335 } while (0); 409 } while (0);
336 UnimplementedError(Ctx->getFlags()); 410 UnimplementedError(Ctx->getFlags());
337 } 411 }
338 412
339 void ARM32::AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, 413 void ARM32::AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
340 CondARM32::Cond Cond) { 414 CondARM32::Cond Cond) {
341 // Note: Loop is used so that we can short ciruit using break; 415 // Note: Loop is used so that we can short ciruit using break;
342 do { 416 do {
343 uint32_t Rt; 417 uint32_t Rt;
344 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 418 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
345 break; 419 break;
346 uint32_t Address; 420 uint32_t Address;
347 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) 421 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset)
348 break; 422 break;
349 // cccc010pub0nnnnttttiiiiiiiiiiii (ARM section A8.8.204, encoding A1; and 423 // STR (immediate) - ARM section A8.8.204, encoding A1:
350 // section 18.8.207, encoding A1). 424 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
425 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
426 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
427 // STRB (immediate) - ARM section A8.8.207, encoding A1:
428 // strb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
429 // strb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
430 // strb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
431 //
432 // cccc010pubw0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
433 // iiiiiiiiiiii=imm12, b=1 if STRB, u=1 if +.
351 constexpr uint32_t InstType = B1; // 010 434 constexpr uint32_t InstType = B1; // 010
352 constexpr bool IsLoad = false; 435 constexpr bool IsLoad = false;
353 const Type Ty = OpRt->getType(); 436 const Type Ty = OpRt->getType();
354 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand? 437 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand?
355 break; 438 break;
356 const bool IsByte = typeWidthInBytes(Ty) == 1; 439 const bool IsByte = typeWidthInBytes(Ty) == 1;
357 // Check for rule violations. 440 // Check for rule violations.
358 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) || 441 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) ||
359 (!isBitSet(P, Address) && isBitSet(W, Address)) || 442 (!isBitSet(P, Address) && isBitSet(W, Address)) ||
360 (!IsByte && 443 (!IsByte &&
361 (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && 444 (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) &&
362 isBitSet(P, Address) && !isBitSet(U, Address) && 445 isBitSet(P, Address) && !isBitSet(U, Address) &&
363 isBitSet(W, Address) && 446 isBitSet(W, Address) &&
364 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))) 447 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)))
448 // Conditions of rule violated.
365 break; 449 break;
366 emitMemOp(Cond, InstType, IsLoad, IsByte, Rt, Address); 450 emitMemOp(Cond, InstType, IsLoad, IsByte, Rt, Address);
367 return; 451 return;
368 } while (0); 452 } while (0);
369 UnimplementedError(Ctx->getFlags()); 453 UnimplementedError(Ctx->getFlags());
370 } 454 }
371 455
372 void ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, 456 void ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn,
373 const Operand *OpSrc1, bool SetFlags, 457 const Operand *OpSrc1, bool SetFlags,
374 CondARM32::Cond Cond) { 458 CondARM32::Cond Cond) {
375 // Note: Loop is used so that we can short circuit using break; 459 // Note: Loop is used so that we can short circuit using break;
376 do { 460 do {
377 uint32_t Rd; 461 uint32_t Rd;
378 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 462 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
379 break; 463 break;
380 uint32_t Rn; 464 uint32_t Rn;
381 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 465 if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
382 break; 466 break;
467 constexpr uint32_t Sub = B1; // 0010
383 uint32_t Src1Value; 468 uint32_t Src1Value;
384 // TODO(kschimpf) Other possible decodings of add. 469 // TODO(kschimpf) Other possible decodings of sub.
385 if (decodeOperand(OpSrc1, Src1Value) == DecodedAsRotatedImm8) { 470 switch (decodeOperand(OpSrc1, Src1Value)) {
386 // Sub (Immediate): See ARM section A8.8.222, rule A1. 471 default:
387 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 472 break;
388 // s=SetFlags and iiiiiiiiiiii=Src1Value 473 case DecodedAsRegister: {
389 if (!isConditionDefined(Cond) || (Rd == RegARM32::Reg_pc && SetFlags) || 474 // SUB (register) - ARM section A8.8.223, encoding A1:
390 (Rn == RegARM32::Reg_lr) || (Rn == RegARM32::Reg_pc && SetFlags)) 475 // sub{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
476 // SUB (SP minus register): See ARM section 8.8.226, encoding A1:
477 // sub{s}<c> <Rd>, sp, <Rm>{, <Shift>}
478 //
479 // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
480 // mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags.
481 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, 0);
482 constexpr uint32_t InstType = 0; // i.e. register
483 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
391 // Conditions of rule violated. 484 // Conditions of rule violated.
392 break; 485 break;
393 constexpr uint32_t Add = B1; // 0010 486 emitType01(Cond, InstType, Sub, SetFlags, Rn, Rd, Src1Value);
487 return;
488 }
489 case DecodedAsRotatedImm8: {
490 // Sub (Immediate) - ARM section A8.8.222, encoding A1:
491 // sub{s}<c> <Rd>, <Rn>, #<RotatedImm8>
492 // Sub (Sp minus immediate) - ARM section A8.*.225, encoding A1:
493 // sub{s}<c> sp, <Rn>, #<RotatedImm8>
494 //
495 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
496 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8
497 if (Rd == RegARM32::Encoded_Reg_pc)
498 // Conditions of rule violated.
499 break;
394 constexpr uint32_t InstType = 1; 500 constexpr uint32_t InstType = 1;
395 emitType01(Cond, InstType, Add, SetFlags, Rn, Rd, Src1Value); 501 emitType01(Cond, InstType, Sub, SetFlags, Rn, Rd, Src1Value);
396 return; 502 return;
397 } 503 }
504 }
398 } while (0); 505 } while (0);
399 UnimplementedError(Ctx->getFlags()); 506 UnimplementedError(Ctx->getFlags());
400 } 507 }
401 508
402 } // end of namespace Ice 509 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/DartARM32/assembler_arm.h ('k') | tests_lit/assembler/arm32/add.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698