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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1418523002: Add hybrid assembler concept to 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
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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 static constexpr uint32_t kRotateShift = 8; 63 static constexpr uint32_t kRotateShift = 8;
64 64
65 // Shift instruction register fields encodings. 65 // Shift instruction register fields encodings.
66 static constexpr uint32_t kShiftImmShift = 7; 66 static constexpr uint32_t kShiftImmShift = 7;
67 static constexpr uint32_t kShiftImmBits = 5; 67 static constexpr uint32_t kShiftImmBits = 5;
68 static constexpr uint32_t kShiftShift = 5; 68 static constexpr uint32_t kShiftShift = 5;
69 69
70 static constexpr uint32_t kImmed12Bits = 12; 70 static constexpr uint32_t kImmed12Bits = 12;
71 static constexpr uint32_t kImm12Shift = 0; 71 static constexpr uint32_t kImm12Shift = 0;
72 72
73 // Type of instruction encoding (bits 25-27).
74 static constexpr uint32_t kInstTypeRegister = 0; // i.e. 000
75 static constexpr uint32_t kInstTypeImmediate = 1; // i.e. 001
76
73 inline uint32_t encodeBool(bool b) { return b ? 1 : 0; } 77 inline uint32_t encodeBool(bool b) { return b ? 1 : 0; }
74 78
75 inline uint32_t encodeGPRRegister(RegARM32::GPRRegister Rn) { 79 inline uint32_t encodeGPRRegister(RegARM32::GPRRegister Rn) {
76 return static_cast<uint32_t>(Rn); 80 return static_cast<uint32_t>(Rn);
77 } 81 }
78 82
79 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) { 83 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) {
80 return R != RegARM32::Encoded_Not_GPR; 84 return R != RegARM32::Encoded_Not_GPR;
81 } 85 }
82 86
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 OperandARM32Mem::Offset); 196 OperandARM32Mem::Offset);
193 return DecodedAsImmRegOffset; 197 return DecodedAsImmRegOffset;
194 } 198 }
195 return CantDecode; 199 return CantDecode;
196 } 200 }
197 201
198 } // end of anonymous namespace 202 } // end of anonymous namespace
199 203
200 namespace Ice { 204 namespace Ice {
201 205
206 size_t ARM32::TextInstFixup::emit(GlobalContext *Ctx,
207 RelocOffsetT OverrideOffset,
208 bool IsPCRel) const {
209 (void)OverrideOffset;
210 (void)IsPCRel;
211 Ctx->getStrEmit() << Message << "\n";
212 static constexpr size_t FixupSize = 4; // i.e. #bytes in instruction.
213 return FixupSize;
214 }
215
202 Label *ARM32::AssemblerARM32::getOrCreateLabel(SizeT Number, 216 Label *ARM32::AssemblerARM32::getOrCreateLabel(SizeT Number,
203 LabelVector &Labels) { 217 LabelVector &Labels) {
204 Label *L = nullptr; 218 Label *L = nullptr;
205 if (Number == Labels.size()) { 219 if (Number == Labels.size()) {
206 L = new (this->allocate<Label>()) Label(); 220 L = new (this->allocate<Label>()) Label();
207 Labels.push_back(L); 221 Labels.push_back(L);
208 return L; 222 return L;
209 } 223 }
210 if (Number > Labels.size()) { 224 if (Number > Labels.size()) {
211 Labels.resize(Number + 1); 225 Labels.resize(Number + 1);
(...skipping 12 matching lines...) Expand all
224 while (label->isLinked()) { 238 while (label->isLinked()) {
225 intptr_t position = label->getLinkPosition(); 239 intptr_t position = label->getLinkPosition();
226 intptr_t next = Buffer.load<int32_t>(position); 240 intptr_t next = Buffer.load<int32_t>(position);
227 Buffer.store<int32_t>(position, bound - (position + 4)); 241 Buffer.store<int32_t>(position, bound - (position + 4));
228 label->setPosition(next); 242 label->setPosition(next);
229 } 243 }
230 // TODO(kschimpf) Decide if we have near jumps. 244 // TODO(kschimpf) Decide if we have near jumps.
231 label->bindTo(bound); 245 label->bindTo(bound);
232 } 246 }
233 247
248 void ARM32::AssemblerARM32::emitTextInst(const std::string &Text) {
249 AssemblerFixup *F =
250 new (allocate<ARM32::TextInstFixup>()) ARM32::TextInstFixup(Text);
251 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
252 installFixup(F);
253 emitFixup(F);
254 emitInst(0);
255 }
256
234 void ARM32::AssemblerARM32::emitType01(CondARM32::Cond Cond, uint32_t Type, 257 void ARM32::AssemblerARM32::emitType01(CondARM32::Cond Cond, uint32_t Type,
235 uint32_t Opcode, bool SetCc, uint32_t Rn, 258 uint32_t Opcode, bool SetCc, uint32_t Rn,
236 uint32_t Rd, uint32_t Imm12) { 259 uint32_t Rd, uint32_t Imm12) {
237 assert(isGPRRegisterDefined(Rd)); 260 assert(isGPRRegisterDefined(Rd));
238 // TODO(kschimpf): Remove void cast when MINIMAL build allows. 261 // TODO(kschimpf): Remove void cast when MINIMAL build allows.
239 (void)isGPRRegisterDefined(Rd); 262 (void)isGPRRegisterDefined(Rd);
240 assert(Cond != CondARM32::kNone); 263 assert(Cond != CondARM32::kNone);
241 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 264 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
242 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | 265 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) |
243 (Type << kTypeShift) | (Opcode << kOpcodeShift) | 266 (Type << kTypeShift) | (Opcode << kOpcodeShift) |
244 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | 267 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) |
245 (Rd << kRdShift) | Imm12; 268 (Rd << kRdShift) | Imm12;
246 emitInst(Encoding); 269 emitInst(Encoding);
247 } 270 }
248 271
249 void ARM32::AssemblerARM32::emitMemOp(CondARM32::Cond Cond, uint32_t InstType, 272 void ARM32::AssemblerARM32::emitMemOp(CondARM32::Cond Cond, uint32_t InstType,
250 bool IsLoad, bool IsByte, uint32_t Rt, 273 bool IsLoad, bool IsByte, uint32_t Rt,
251 uint32_t Address) { 274 uint32_t Address) {
252 assert(isGPRRegisterDefined(Rt)); 275 assert(isGPRRegisterDefined(Rt));
253 assert(Cond != CondARM32::kNone); 276 assert(Cond != CondARM32::kNone);
254 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 277 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
255 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | 278 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) |
256 (InstType << kTypeShift) | (IsLoad ? L : 0) | 279 (InstType << kTypeShift) | (IsLoad ? L : 0) |
257 (IsByte ? B : 0) | (Rt << kRdShift) | Address; 280 (IsByte ? B : 0) | (Rt << kRdShift) | Address;
258 emitInst(Encoding); 281 emitInst(Encoding);
259 } 282 }
260 283
261 void ARM32::AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn, 284 bool ARM32::AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn,
262 const Operand *OpSrc1, bool SetFlags, 285 const Operand *OpSrc1, bool SetFlags,
263 CondARM32::Cond Cond) { 286 CondARM32::Cond Cond) {
264 // Note: Loop is used so that we can short circuit using break; 287 uint32_t Rd;
265 do { 288 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
266 uint32_t Rd; 289 return false;
267 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 290 uint32_t Rn;
268 break; 291 if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
269 uint32_t Rn; 292 return false;
270 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 293 constexpr uint32_t Add = B2; // 0100
271 break; 294 uint32_t Src1Value;
272 constexpr uint32_t Add = B2; // 0100 295 // TODO(kschimpf) Other possible decodings of add.
273 uint32_t Src1Value; 296 switch (decodeOperand(OpSrc1, Src1Value)) {
274 // TODO(kschimpf) Other possible decodings of add. 297 default:
275 switch (decodeOperand(OpSrc1, Src1Value)) { 298 return false;
276 default: 299 case DecodedAsRegister: {
277 break; 300 // ADD (register) - ARM section A8.8.7, encoding A1:
278 case DecodedAsRegister: { 301 // add{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
279 // ADD (register) - ARM section A8.8.7, encoding A1: 302 // ADD (Sp plus register) - ARM section A8.8.11, encoding A1:
280 // add{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} 303 // add{s}<c> sp, <Rn>, <Rm>{, <shiff>}
281 // ADD (Sp plus register) - ARM section A8.8.11, encoding A1: 304 //
282 // add{s}<c> sp, <Rn>, <Rm>{, <shiff>} 305 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
283 // 306 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags
284 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 307 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, 0);
285 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags 308 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
286 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, 0); 309 // Conditions of rule violated.
287 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) 310 return false;
288 // Conditions of rule violated. 311 emitType01(Cond, kInstTypeRegister, Add, SetFlags, Rn, Rd, Src1Value);
289 break; 312 return true;
290 constexpr uint32_t InstTypeRegister = 0; 313 }
291 emitType01(Cond, InstTypeRegister, Add, SetFlags, Rn, Rd, Src1Value); 314 case DecodedAsRotatedImm8: {
292 return; 315 // ADD (Immediate) - ARM section A8.8.5, encoding A1:
293 } 316 // add{s}<c> <Rd>, <Rn>, #<RotatedImm8>
294 case DecodedAsRotatedImm8: { 317 // ADD (SP plus immediate) - ARM section A8.8.9, encoding A1.
295 // ADD (Immediate) - ARM section A8.8.5, encoding A1: 318 // add{s}<c> <Rd>, sp, #<RotatedImm8>
296 // add{s}<c> <Rd>, <Rn>, #<RotatedImm8> 319 //
297 // ADD (SP plus immediate) - ARM section A8.8.9, encoding A1. 320 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
298 // add{s}<c> <Rd>, sp, #<RotatedImm8> 321 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8.
299 // 322 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
300 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 323 // Conditions of rule violated.
301 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8. 324 return false;
302 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) 325 emitType01(Cond, kInstTypeImmediate, Add, SetFlags, Rn, Rd, Src1Value);
303 // Conditions of rule violated. 326 return true;
304 break; 327 }
305 constexpr uint32_t InstTypeImmediate = 1; 328 };
306 emitType01(Cond, InstTypeImmediate, Add, SetFlags, Rn, Rd, Src1Value);
307 return;
308 }
309 }
310 } while (0);
311 UnimplementedError(Ctx->getFlags());
312 } 329 }
313 330
314 void ARM32::AssemblerARM32::bkpt(uint16_t Imm16) { 331 bool ARM32::AssemblerARM32::bkpt(uint16_t Imm16) {
315 // BKPT - ARM section A*.8.24 - encoding A1: 332 // BKPT - ARM section A*.8.24 - encoding A1:
316 // bkpt #<Imm16> 333 // bkpt #<Imm16>
317 // 334 //
318 // cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and iiiiiiiiiiiiiiii=Imm16 335 // cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and iiiiiiiiiiiiiiii=Imm16
319 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 336 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
320 const uint32_t Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 | 337 const uint32_t Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 |
321 ((Imm16 >> 4) << 8) | B6 | B5 | B4 | (Imm16 & 0xf); 338 ((Imm16 >> 4) << 8) | B6 | B5 | B4 | (Imm16 & 0xf);
322 emitInst(Encoding); 339 emitInst(Encoding);
340 return true;
323 } 341 }
324 342
325 void ARM32::AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) { 343 bool ARM32::AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) {
326 // BX - ARM section A8.8.27, encoding A1: 344 // BX - ARM section A8.8.27, encoding A1:
327 // bx<c> <Rm> 345 // bx<c> <Rm>
328 // 346 //
329 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond. 347 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond.
330 assert(isGPRRegisterDefined(Rm)); 348 if (!(isGPRRegisterDefined(Rm) && isConditionDefined(Cond)))
331 // TODO(kschimpf): Remove void cast when MINIMAL build allows. 349 return false;
332 (void)isGPRRegisterDefined(Rm);
333 assert(isConditionDefined(Cond));
334 (void)isConditionDefined(Cond);
335 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 350 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
336 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | 351 const uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 |
337 B21 | (0xfff << 8) | B4 | 352 B21 | (0xfff << 8) | B4 |
338 (encodeGPRRegister(Rm) << kRmShift); 353 (encodeGPRRegister(Rm) << kRmShift);
339 emitInst(Encoding); 354 emitInst(Encoding);
355 return true;
340 } 356 }
341 357
342 void ARM32::AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, 358 bool ARM32::AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
343 CondARM32::Cond Cond) { 359 CondARM32::Cond Cond) {
344 // Note: Loop is used so that we can short ciruit using break; 360 uint32_t Rt;
345 do { 361 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
346 uint32_t Rt; 362 return false;
347 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 363 uint32_t Address;
348 break; 364 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset)
349 uint32_t Address; 365 return false;
350 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) 366 // LDR (immediate) - ARM section A8.8.63, encoding A1:
351 break; 367 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
352 // LDR (immediate) - ARM section A8.8.63, encoding A1: 368 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
353 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 369 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
354 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 370 // LDRB (immediate) - ARM section A8.8.68, encoding A1:
355 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 371 // ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
356 // LDRB (immediate) - ARM section A8.8.68, encoding A1: 372 // ldrb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
357 // ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 373 // ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
358 // ldrb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 374 //
359 // ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 375 // cccc010pubw1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
360 // 376 // iiiiiiiiiiii=imm12, b=1 if STRB, u=1 if +.
361 // cccc010pubw1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, 377 constexpr bool IsLoad = true;
362 // iiiiiiiiiiii=imm12, b=1 if STRB, u=1 if +. 378 const Type Ty = OpRt->getType();
363 constexpr uint32_t InstType = B1; // 010 379 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand?
364 constexpr bool IsLoad = true; 380 return false;
365 const Type Ty = OpRt->getType(); 381 const bool IsByte = typeWidthInBytes(Ty) == 1;
366 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand? 382 // Check conditions of rules violated.
367 break; 383 if (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc)
368 const bool IsByte = typeWidthInBytes(Ty) == 1; 384 return false;
369 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) || 385 if (!isBitSet(P, Address) && isBitSet(W, Address))
370 (!isBitSet(P, Address) && isBitSet(W, Address)) || 386 return false;
371 (!IsByte && 387 if (!IsByte && (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) &&
372 (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && 388 !isBitSet(P, Address) && isBitSet(U, Address) & !isBitSet(W, Address) &&
373 !isBitSet(P, Address) && 389 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))
374 isBitSet(U, Address) & !isBitSet(W, Address) && 390 return false;
375 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))) 391 emitMemOp(Cond, kInstTypeImmediate, IsLoad, IsByte, Rt, Address);
376 break; 392 return true;
377 emitMemOp(Cond, InstType, IsLoad, IsByte, Rt, Address);
378 return;
379 } while (0);
380 UnimplementedError(Ctx->getFlags());
381 } 393 }
382 394
383 void ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, 395 bool ARM32::AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
384 CondARM32::Cond Cond) { 396 CondARM32::Cond Cond) {
385 // Note: Loop is used so that we can short ciruit using break; 397 uint32_t Rd;
386 do { 398 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
387 uint32_t Rd; 399 return false;
388 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 400 uint32_t Src;
389 break; 401 // TODO(kschimpf) Handle other forms of mov.
390 uint32_t Src; 402 if (decodeOperand(OpSrc, Src) != DecodedAsRotatedImm8)
391 // TODO(kschimpf) Handle other forms of mov. 403 return false;
392 if (decodeOperand(OpSrc, Src) == DecodedAsRotatedImm8) { 404 // MOV (immediate) - ARM section A8.8.102, encoding A1:
393 // MOV (immediate) - ARM section A8.8.102, encoding A1: 405 // mov{S}<c> <Rd>, #<RotatedImm8>
394 // mov{S}<c> <Rd>, #<RotatedImm8> 406 //
395 // 407 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd,
396 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd, 408 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this
397 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this 409 // assembler.
398 // assembler. 410 constexpr bool SetFlags = false;
399 constexpr bool SetFlags = false; 411 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
400 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) 412 // Conditions of rule violated.
401 // Conditions of rule violated. 413 return false;
402 break; 414 constexpr uint32_t Rn = 0;
403 constexpr uint32_t Rn = 0; 415 constexpr uint32_t Mov = B3 | B2 | B0; // 1101.
404 constexpr uint32_t Mov = B3 | B2 | B0; // 1101. 416 emitType01(Cond, kInstTypeImmediate, Mov, SetFlags, Rn, Rd, Src);
405 constexpr uint32_t InstType = 1; 417 return true;
406 emitType01(Cond, InstType, Mov, SetFlags, Rn, Rd, Src);
407 return;
408 }
409 } while (0);
410 UnimplementedError(Ctx->getFlags());
411 } 418 }
412 419
413 void ARM32::AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, 420 bool ARM32::AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
414 CondARM32::Cond Cond) { 421 CondARM32::Cond Cond) {
415 // Note: Loop is used so that we can short ciruit using break; 422 uint32_t Rt;
416 do { 423 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
417 uint32_t Rt; 424 return false;
418 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 425 uint32_t Address;
419 break; 426 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset)
420 uint32_t Address; 427 return false;
421 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) 428 // STR (immediate) - ARM section A8.8.204, encoding A1:
422 break; 429 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
423 // STR (immediate) - ARM section A8.8.204, encoding A1: 430 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
424 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 431 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
425 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 432 // STRB (immediate) - ARM section A8.8.207, encoding A1:
426 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 433 // strb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
427 // STRB (immediate) - ARM section A8.8.207, encoding A1: 434 // strb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
428 // strb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 435 // strb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
429 // strb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 436 //
430 // strb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 437 // cccc010pubw0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
431 // 438 // iiiiiiiiiiii=imm12, b=1 if STRB, u=1 if +.
432 // cccc010pubw0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, 439 constexpr bool IsLoad = false;
433 // iiiiiiiiiiii=imm12, b=1 if STRB, u=1 if +. 440 const Type Ty = OpRt->getType();
434 constexpr uint32_t InstType = B1; // 010 441 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand?
435 constexpr bool IsLoad = false; 442 return false;
436 const Type Ty = OpRt->getType(); 443 const bool IsByte = typeWidthInBytes(Ty) == 1;
437 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand? 444 // Check for rule violations.
438 break; 445 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc))
439 const bool IsByte = typeWidthInBytes(Ty) == 1; 446 return false;
440 // Check for rule violations. 447 if (!isBitSet(P, Address) && isBitSet(W, Address))
441 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) || 448 return false;
442 (!isBitSet(P, Address) && isBitSet(W, Address)) || 449 if (!IsByte && (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) &&
443 (!IsByte && 450 isBitSet(P, Address) && !isBitSet(U, Address) && isBitSet(W, Address) &&
444 (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && 451 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))
445 isBitSet(P, Address) && !isBitSet(U, Address) && 452 return false;
446 isBitSet(W, Address) && 453 emitMemOp(Cond, kInstTypeImmediate, IsLoad, IsByte, Rt, Address);
447 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))) 454 return true;
448 // Conditions of rule violated.
449 break;
450 emitMemOp(Cond, InstType, IsLoad, IsByte, Rt, Address);
451 return;
452 } while (0);
453 UnimplementedError(Ctx->getFlags());
454 } 455 }
455 456
456 void ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, 457 bool ARM32::AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn,
457 const Operand *OpSrc1, bool SetFlags, 458 const Operand *OpSrc1, bool SetFlags,
458 CondARM32::Cond Cond) { 459 CondARM32::Cond Cond) {
459 // Note: Loop is used so that we can short circuit using break; 460 uint32_t Rd;
460 do { 461 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
461 uint32_t Rd; 462 return false;
462 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 463 uint32_t Rn;
463 break; 464 if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
464 uint32_t Rn; 465 return false;
465 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 466 constexpr uint32_t Sub = B1; // 0010
466 break; 467 uint32_t Src1Value;
467 constexpr uint32_t Sub = B1; // 0010 468 // TODO(kschimpf) Other possible decodings of sub.
468 uint32_t Src1Value; 469 switch (decodeOperand(OpSrc1, Src1Value)) {
469 // TODO(kschimpf) Other possible decodings of sub. 470 default:
470 switch (decodeOperand(OpSrc1, Src1Value)) { 471 return false;
471 default: 472 case DecodedAsRegister: {
472 break; 473 // SUB (register) - ARM section A8.8.223, encoding A1:
473 case DecodedAsRegister: { 474 // sub{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
474 // SUB (register) - ARM section A8.8.223, encoding A1: 475 // SUB (SP minus register): See ARM section 8.8.226, encoding A1:
475 // sub{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} 476 // sub{s}<c> <Rd>, sp, <Rm>{, <Shift>}
476 // SUB (SP minus register): See ARM section 8.8.226, encoding A1: 477 //
477 // sub{s}<c> <Rd>, sp, <Rm>{, <Shift>} 478 // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
478 // 479 // mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags.
479 // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 480 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, 0);
480 // mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags. 481 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags))
481 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, 0); 482 // Conditions of rule violated.
482 constexpr uint32_t InstType = 0; // i.e. register 483 return false;
483 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) 484 emitType01(Cond, kInstTypeRegister, Sub, SetFlags, Rn, Rd, Src1Value);
484 // Conditions of rule violated. 485 return true;
485 break; 486 }
486 emitType01(Cond, InstType, Sub, SetFlags, Rn, Rd, Src1Value); 487 case DecodedAsRotatedImm8: {
487 return; 488 // Sub (Immediate) - ARM section A8.8.222, encoding A1:
488 } 489 // sub{s}<c> <Rd>, <Rn>, #<RotatedImm8>
489 case DecodedAsRotatedImm8: { 490 // Sub (Sp minus immediate) - ARM section A8.*.225, encoding A1:
490 // Sub (Immediate) - ARM section A8.8.222, encoding A1: 491 // sub{s}<c> sp, <Rn>, #<RotatedImm8>
491 // sub{s}<c> <Rd>, <Rn>, #<RotatedImm8> 492 //
492 // Sub (Sp minus immediate) - ARM section A8.*.225, encoding A1: 493 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
493 // sub{s}<c> sp, <Rn>, #<RotatedImm8> 494 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8
494 // 495 if (Rd == RegARM32::Encoded_Reg_pc)
495 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 496 // Conditions of rule violated.
496 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8 497 return false;
497 if (Rd == RegARM32::Encoded_Reg_pc) 498 emitType01(Cond, kInstTypeImmediate, Sub, SetFlags, Rn, Rd, Src1Value);
498 // Conditions of rule violated. 499 return true;
499 break; 500 }
500 constexpr uint32_t InstType = 1; 501 }
501 emitType01(Cond, InstType, Sub, SetFlags, Rn, Rd, Src1Value);
502 return;
503 }
504 }
505 } while (0);
506 UnimplementedError(Ctx->getFlags());
507 } 502 }
508 503
509 } // end of namespace Ice 504 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698