1 //===-- XtensaMCCodeEmitter.cpp - Convert Xtensa Code to Machine Code -----===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 6 // See https://llvm.org/LICENSE.txt for license information. 7 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 8 // 9 //===----------------------------------------------------------------------===// 10 // 11 // This file implements the XtensaMCCodeEmitter class. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "MCTargetDesc/XtensaFixupKinds.h" 16 #include "MCTargetDesc/XtensaMCExpr.h" 17 #include "MCTargetDesc/XtensaMCTargetDesc.h" 18 #include "llvm/MC/MCCodeEmitter.h" 19 #include "llvm/MC/MCContext.h" 20 #include "llvm/MC/MCExpr.h" 21 #include "llvm/MC/MCInst.h" 22 #include "llvm/MC/MCInstrInfo.h" 23 #include "llvm/MC/MCRegisterInfo.h" 24 25 #define GET_INSTRMAP_INFO 26 #include "XtensaGenInstrInfo.inc" 27 #undef GET_INSTRMAP_INFO 28 29 using namespace llvm; 30 31 #define DEBUG_TYPE "mccodeemitter" 32 33 namespace { 34 class XtensaMCCodeEmitter : public MCCodeEmitter { 35 const MCInstrInfo &MCII; 36 MCContext &Ctx; 37 bool IsLittleEndian; 38 39 public: 40 XtensaMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool isLE) 41 : MCII(mcii), Ctx(ctx), IsLittleEndian(isLE) {} 42 43 ~XtensaMCCodeEmitter() {} 44 45 // OVerride MCCodeEmitter. 46 void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB, 47 SmallVectorImpl<MCFixup> &Fixups, 48 const MCSubtargetInfo &STI) const override; 49 50 private: 51 // Automatically generated by TableGen. 52 uint64_t getBinaryCodeForInstr(const MCInst &MI, 53 SmallVectorImpl<MCFixup> &Fixups, 54 const MCSubtargetInfo &STI) const; 55 56 // Called by the TableGen code to get the binary encoding of operand 57 // MO in MI. Fixups is the list of fixups against MI. 58 uint32_t getMachineOpValue(const MCInst &MI, const MCOperand &MO, 59 SmallVectorImpl<MCFixup> &Fixups, 60 const MCSubtargetInfo &STI) const; 61 62 uint32_t getJumpTargetEncoding(const MCInst &MI, unsigned int OpNum, 63 SmallVectorImpl<MCFixup> &Fixups, 64 const MCSubtargetInfo &STI) const; 65 66 uint32_t getBranchTargetEncoding(const MCInst &MI, unsigned int OpNum, 67 SmallVectorImpl<MCFixup> &Fixups, 68 const MCSubtargetInfo &STI) const; 69 70 uint32_t getCallEncoding(const MCInst &MI, unsigned int OpNum, 71 SmallVectorImpl<MCFixup> &Fixups, 72 const MCSubtargetInfo &STI) const; 73 74 uint32_t getL32RTargetEncoding(const MCInst &MI, unsigned OpNum, 75 SmallVectorImpl<MCFixup> &Fixups, 76 const MCSubtargetInfo &STI) const; 77 78 uint32_t getMemRegEncoding(const MCInst &MI, unsigned OpNo, 79 SmallVectorImpl<MCFixup> &Fixups, 80 const MCSubtargetInfo &STI) const; 81 82 uint32_t getImm8OpValue(const MCInst &MI, unsigned OpNo, 83 SmallVectorImpl<MCFixup> &Fixups, 84 const MCSubtargetInfo &STI) const; 85 86 uint32_t getImm8_sh8OpValue(const MCInst &MI, unsigned OpNo, 87 SmallVectorImpl<MCFixup> &Fixups, 88 const MCSubtargetInfo &STI) const; 89 90 uint32_t getImm12OpValue(const MCInst &MI, unsigned OpNo, 91 SmallVectorImpl<MCFixup> &Fixups, 92 const MCSubtargetInfo &STI) const; 93 94 uint32_t getUimm4OpValue(const MCInst &MI, unsigned OpNo, 95 SmallVectorImpl<MCFixup> &Fixups, 96 const MCSubtargetInfo &STI) const; 97 98 uint32_t getUimm5OpValue(const MCInst &MI, unsigned OpNo, 99 SmallVectorImpl<MCFixup> &Fixups, 100 const MCSubtargetInfo &STI) const; 101 102 uint32_t getImm1_16OpValue(const MCInst &MI, unsigned OpNo, 103 SmallVectorImpl<MCFixup> &Fixups, 104 const MCSubtargetInfo &STI) const; 105 106 uint32_t getImm1n_15OpValue(const MCInst &MI, unsigned OpNo, 107 SmallVectorImpl<MCFixup> &Fixups, 108 const MCSubtargetInfo &STI) const; 109 110 uint32_t getImm32n_95OpValue(const MCInst &MI, unsigned OpNo, 111 SmallVectorImpl<MCFixup> &Fixups, 112 const MCSubtargetInfo &STI) const; 113 114 uint32_t getShimm1_31OpValue(const MCInst &MI, unsigned OpNo, 115 SmallVectorImpl<MCFixup> &Fixups, 116 const MCSubtargetInfo &STI) const; 117 118 uint32_t getB4constOpValue(const MCInst &MI, unsigned OpNo, 119 SmallVectorImpl<MCFixup> &Fixups, 120 const MCSubtargetInfo &STI) const; 121 122 uint32_t getB4constuOpValue(const MCInst &MI, unsigned OpNo, 123 SmallVectorImpl<MCFixup> &Fixups, 124 const MCSubtargetInfo &STI) const; 125 }; 126 } // namespace 127 128 MCCodeEmitter *llvm::createXtensaMCCodeEmitter(const MCInstrInfo &MCII, 129 MCContext &Ctx) { 130 return new XtensaMCCodeEmitter(MCII, Ctx, true); 131 } 132 133 void XtensaMCCodeEmitter::encodeInstruction(const MCInst &MI, 134 SmallVectorImpl<char> &CB, 135 SmallVectorImpl<MCFixup> &Fixups, 136 const MCSubtargetInfo &STI) const { 137 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 138 unsigned Size = MCII.get(MI.getOpcode()).getSize(); 139 140 if (IsLittleEndian) { 141 // Little-endian insertion of Size bytes. 142 unsigned ShiftValue = 0; 143 for (unsigned I = 0; I != Size; ++I) { 144 CB.push_back(char(Bits >> ShiftValue)); 145 ShiftValue += 8; 146 } 147 } else { 148 // TODO Big-endian insertion of Size bytes. 149 report_fatal_error("Big-endian mode currently is not supported!"); 150 } 151 } 152 153 uint32_t 154 XtensaMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, 155 SmallVectorImpl<MCFixup> &Fixups, 156 const MCSubtargetInfo &STI) const { 157 if (MO.isReg()) 158 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 159 if (MO.isImm()) { 160 uint32_t Res = static_cast<uint32_t>(MO.getImm()); 161 return Res; 162 } 163 164 report_fatal_error("Unhandled expression!"); 165 return 0; 166 } 167 168 uint32_t 169 XtensaMCCodeEmitter::getJumpTargetEncoding(const MCInst &MI, unsigned int OpNum, 170 SmallVectorImpl<MCFixup> &Fixups, 171 const MCSubtargetInfo &STI) const { 172 const MCOperand &MO = MI.getOperand(OpNum); 173 174 if (MO.isImm()) 175 return MO.getImm(); 176 177 const MCExpr *Expr = MO.getExpr(); 178 Fixups.push_back(MCFixup::create( 179 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_jump_18), MI.getLoc())); 180 return 0; 181 } 182 183 uint32_t XtensaMCCodeEmitter::getBranchTargetEncoding( 184 const MCInst &MI, unsigned int OpNum, SmallVectorImpl<MCFixup> &Fixups, 185 const MCSubtargetInfo &STI) const { 186 const MCOperand &MO = MI.getOperand(OpNum); 187 if (MO.isImm()) 188 return static_cast<uint32_t>(MO.getImm()); 189 190 const MCExpr *Expr = MO.getExpr(); 191 switch (MI.getOpcode()) { 192 case Xtensa::BEQZ: 193 case Xtensa::BGEZ: 194 case Xtensa::BLTZ: 195 case Xtensa::BNEZ: 196 Fixups.push_back(MCFixup::create( 197 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_branch_12), MI.getLoc())); 198 return 0; 199 case Xtensa::BEQZ_N: 200 case Xtensa::BNEZ_N: 201 Fixups.push_back(MCFixup::create( 202 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_branch_6), MI.getLoc())); 203 return 0; 204 default: 205 Fixups.push_back(MCFixup::create( 206 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_branch_8), MI.getLoc())); 207 return 0; 208 } 209 } 210 211 uint32_t 212 XtensaMCCodeEmitter::getCallEncoding(const MCInst &MI, unsigned int OpNum, 213 SmallVectorImpl<MCFixup> &Fixups, 214 const MCSubtargetInfo &STI) const { 215 const MCOperand &MO = MI.getOperand(OpNum); 216 if (MO.isImm()) { 217 int32_t Res = MO.getImm(); 218 if (Res & 0x3) { 219 llvm_unreachable("Unexpected operand value!"); 220 } 221 Res >>= 2; 222 return Res; 223 } 224 225 assert((MO.isExpr()) && "Unexpected operand value!"); 226 const MCExpr *Expr = MO.getExpr(); 227 Fixups.push_back(MCFixup::create( 228 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_call_18), MI.getLoc())); 229 return 0; 230 } 231 232 uint32_t 233 XtensaMCCodeEmitter::getL32RTargetEncoding(const MCInst &MI, unsigned OpNum, 234 SmallVectorImpl<MCFixup> &Fixups, 235 const MCSubtargetInfo &STI) const { 236 const MCOperand &MO = MI.getOperand(OpNum); 237 if (MO.isImm()) { 238 int32_t Res = MO.getImm(); 239 // We don't check first 2 bits, because in these bits we could store first 2 240 // bits of instruction address 241 Res >>= 2; 242 return Res; 243 } 244 245 assert((MO.isExpr()) && "Unexpected operand value!"); 246 247 Fixups.push_back(MCFixup::create( 248 0, MO.getExpr(), MCFixupKind(Xtensa::fixup_xtensa_l32r_16), MI.getLoc())); 249 return 0; 250 } 251 252 uint32_t 253 XtensaMCCodeEmitter::getMemRegEncoding(const MCInst &MI, unsigned OpNo, 254 SmallVectorImpl<MCFixup> &Fixups, 255 const MCSubtargetInfo &STI) const { 256 assert(MI.getOperand(OpNo + 1).isImm()); 257 258 uint32_t Res = static_cast<uint32_t>(MI.getOperand(OpNo + 1).getImm()); 259 260 switch (MI.getOpcode()) { 261 case Xtensa::S16I: 262 case Xtensa::L16SI: 263 case Xtensa::L16UI: 264 if (Res & 0x1) { 265 report_fatal_error("Unexpected operand value!"); 266 } 267 Res >>= 1; 268 break; 269 case Xtensa::S32I: 270 case Xtensa::L32I: 271 case Xtensa::S32I_N: 272 case Xtensa::L32I_N: 273 if (Res & 0x3) { 274 report_fatal_error("Unexpected operand value!"); 275 } 276 Res >>= 2; 277 break; 278 } 279 280 switch (MI.getOpcode()) { 281 case Xtensa::S32I_N: 282 case Xtensa::L32I_N: 283 assert((isUInt<4>(Res)) && "Unexpected operand value!"); 284 break; 285 default: 286 assert((isUInt<8>(Res)) && "Unexpected operand value!"); 287 break; 288 } 289 290 uint32_t OffBits = Res << 4; 291 uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 292 293 return ((OffBits & 0xFF0) | RegBits); 294 } 295 296 uint32_t XtensaMCCodeEmitter::getImm8OpValue(const MCInst &MI, unsigned OpNo, 297 SmallVectorImpl<MCFixup> &Fixups, 298 const MCSubtargetInfo &STI) const { 299 const MCOperand &MO = MI.getOperand(OpNo); 300 int32_t Res = MO.getImm(); 301 302 assert(((Res >= -128) && (Res <= 127)) && "Unexpected operand value!"); 303 304 return (Res & 0xff); 305 } 306 307 uint32_t 308 XtensaMCCodeEmitter::getImm8_sh8OpValue(const MCInst &MI, unsigned OpNo, 309 SmallVectorImpl<MCFixup> &Fixups, 310 const MCSubtargetInfo &STI) const { 311 const MCOperand &MO = MI.getOperand(OpNo); 312 int32_t Res = MO.getImm(); 313 314 assert(((Res >= -32768) && (Res <= 32512) && ((Res & 0xff) == 0)) && 315 "Unexpected operand value!"); 316 317 return (Res & 0xffff); 318 } 319 320 uint32_t 321 XtensaMCCodeEmitter::getImm12OpValue(const MCInst &MI, unsigned OpNo, 322 SmallVectorImpl<MCFixup> &Fixups, 323 const MCSubtargetInfo &STI) const { 324 const MCOperand &MO = MI.getOperand(OpNo); 325 int32_t Res = MO.getImm(); 326 327 assert(((Res >= -2048) && (Res <= 2047)) && "Unexpected operand value!"); 328 329 return (Res & 0xfff); 330 } 331 332 uint32_t 333 XtensaMCCodeEmitter::getUimm4OpValue(const MCInst &MI, unsigned OpNo, 334 SmallVectorImpl<MCFixup> &Fixups, 335 const MCSubtargetInfo &STI) const { 336 const MCOperand &MO = MI.getOperand(OpNo); 337 uint32_t Res = static_cast<uint32_t>(MO.getImm()); 338 339 assert((Res <= 15) && "Unexpected operand value!"); 340 341 return Res & 0xf; 342 } 343 344 uint32_t 345 XtensaMCCodeEmitter::getUimm5OpValue(const MCInst &MI, unsigned OpNo, 346 SmallVectorImpl<MCFixup> &Fixups, 347 const MCSubtargetInfo &STI) const { 348 const MCOperand &MO = MI.getOperand(OpNo); 349 uint32_t Res = static_cast<uint32_t>(MO.getImm()); 350 351 assert((Res <= 31) && "Unexpected operand value!"); 352 353 return (Res & 0x1f); 354 } 355 356 uint32_t 357 XtensaMCCodeEmitter::getShimm1_31OpValue(const MCInst &MI, unsigned OpNo, 358 SmallVectorImpl<MCFixup> &Fixups, 359 const MCSubtargetInfo &STI) const { 360 const MCOperand &MO = MI.getOperand(OpNo); 361 uint32_t Res = static_cast<uint32_t>(MO.getImm()); 362 363 assert(((Res >= 1) && (Res <= 31)) && "Unexpected operand value!"); 364 365 return ((32 - Res) & 0x1f); 366 } 367 368 uint32_t 369 XtensaMCCodeEmitter::getImm1_16OpValue(const MCInst &MI, unsigned OpNo, 370 SmallVectorImpl<MCFixup> &Fixups, 371 const MCSubtargetInfo &STI) const { 372 const MCOperand &MO = MI.getOperand(OpNo); 373 uint32_t Res = static_cast<uint32_t>(MO.getImm()); 374 375 assert(((Res >= 1) && (Res <= 16)) && "Unexpected operand value!"); 376 377 return (Res - 1); 378 } 379 380 uint32_t 381 XtensaMCCodeEmitter::getImm1n_15OpValue(const MCInst &MI, unsigned OpNo, 382 SmallVectorImpl<MCFixup> &Fixups, 383 const MCSubtargetInfo &STI) const { 384 const MCOperand &MO = MI.getOperand(OpNo); 385 int32_t Res = static_cast<int32_t>(MO.getImm()); 386 387 assert(((Res >= -1) && (Res <= 15) && (Res != 0)) && 388 "Unexpected operand value!"); 389 390 if (Res < 0) 391 Res = 0; 392 393 return Res; 394 } 395 396 uint32_t 397 XtensaMCCodeEmitter::getImm32n_95OpValue(const MCInst &MI, unsigned OpNo, 398 SmallVectorImpl<MCFixup> &Fixups, 399 const MCSubtargetInfo &STI) const { 400 const MCOperand &MO = MI.getOperand(OpNo); 401 int32_t Res = static_cast<int32_t>(MO.getImm()); 402 403 assert(((Res >= -32) && (Res <= 95)) && "Unexpected operand value!"); 404 405 return Res; 406 } 407 408 uint32_t 409 XtensaMCCodeEmitter::getB4constOpValue(const MCInst &MI, unsigned OpNo, 410 SmallVectorImpl<MCFixup> &Fixups, 411 const MCSubtargetInfo &STI) const { 412 const MCOperand &MO = MI.getOperand(OpNo); 413 uint32_t Res = static_cast<uint32_t>(MO.getImm()); 414 415 switch (Res) { 416 case 0xffffffff: 417 Res = 0; 418 break; 419 case 1: 420 case 2: 421 case 3: 422 case 4: 423 case 5: 424 case 6: 425 case 7: 426 case 8: 427 break; 428 case 10: 429 Res = 9; 430 break; 431 case 12: 432 Res = 10; 433 break; 434 case 16: 435 Res = 11; 436 break; 437 case 32: 438 Res = 12; 439 break; 440 case 64: 441 Res = 13; 442 break; 443 case 128: 444 Res = 14; 445 break; 446 case 256: 447 Res = 15; 448 break; 449 default: 450 llvm_unreachable("Unexpected operand value!"); 451 } 452 453 return Res; 454 } 455 456 uint32_t 457 XtensaMCCodeEmitter::getB4constuOpValue(const MCInst &MI, unsigned OpNo, 458 SmallVectorImpl<MCFixup> &Fixups, 459 const MCSubtargetInfo &STI) const { 460 const MCOperand &MO = MI.getOperand(OpNo); 461 uint32_t Res = static_cast<uint32_t>(MO.getImm()); 462 463 switch (Res) { 464 case 32768: 465 Res = 0; 466 break; 467 case 65536: 468 Res = 1; 469 break; 470 case 2: 471 case 3: 472 case 4: 473 case 5: 474 case 6: 475 case 7: 476 case 8: 477 break; 478 case 10: 479 Res = 9; 480 break; 481 case 12: 482 Res = 10; 483 break; 484 case 16: 485 Res = 11; 486 break; 487 case 32: 488 Res = 12; 489 break; 490 case 64: 491 Res = 13; 492 break; 493 case 128: 494 Res = 14; 495 break; 496 case 256: 497 Res = 15; 498 break; 499 default: 500 llvm_unreachable("Unexpected operand value!"); 501 } 502 503 return Res; 504 } 505 #include "XtensaGenMCCodeEmitter.inc" 506