Mips16InstrInfo.td revision 69f8e0935af16622ca13d26e6a66464d3c1f3da4
1//===- Mips16InstrInfo.td - Target Description for Mips16 -*- tablegen -*-=// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file describes Mips16 instructions. 11// 12//===----------------------------------------------------------------------===// 13// 14// 15// Mips Address 16// 17def addr16 : 18 ComplexPattern<iPTR, 3, "selectAddr16", [frameindex], [SDNPWantParent]>; 19 20// 21// Address operand 22def mem16 : Operand<i32> { 23 let PrintMethod = "printMemOperand"; 24 let MIOperandInfo = (ops CPU16Regs, simm16, CPU16RegsPlusSP); 25 let EncoderMethod = "getMemEncoding"; 26} 27 28def mem16_ea : Operand<i32> { 29 let PrintMethod = "printMemOperandEA"; 30 let MIOperandInfo = (ops CPU16RegsPlusSP, simm16); 31 let EncoderMethod = "getMemEncoding"; 32} 33 34// 35// 36// I8 instruction format 37// 38 39class FI816_ins_base<bits<3> _func, string asmstr, 40 string asmstr2, InstrItinClass itin>: 41 FI816<_func, (outs), (ins simm16:$imm), !strconcat(asmstr, asmstr2), 42 [], itin>; 43 44 45class FI816_SP_ins<bits<3> _func, string asmstr, 46 InstrItinClass itin>: 47 FI816_ins_base<_func, asmstr, "\t$$sp, $imm # 16 bit inst", itin>; 48 49// 50// RI instruction format 51// 52 53 54class FRI16_ins_base<bits<5> op, string asmstr, string asmstr2, 55 InstrItinClass itin>: 56 FRI16<op, (outs CPU16Regs:$rx), (ins simm16:$imm), 57 !strconcat(asmstr, asmstr2), [], itin>; 58 59class FRI16_ins<bits<5> op, string asmstr, 60 InstrItinClass itin>: 61 FRI16_ins_base<op, asmstr, "\t$rx, $imm \t# 16 bit inst", itin>; 62 63class FRI16R_ins_base<bits<5> op, string asmstr, string asmstr2, 64 InstrItinClass itin>: 65 FRI16<op, (outs), (ins CPU16Regs:$rx, simm16:$imm), 66 !strconcat(asmstr, asmstr2), [], itin>; 67 68class FRI16R_ins<bits<5> op, string asmstr, 69 InstrItinClass itin>: 70 FRI16R_ins_base<op, asmstr, "\t$rx, $imm \t# 16 bit inst", itin>; 71 72class F2RI16_ins<bits<5> _op, string asmstr, 73 InstrItinClass itin>: 74 FRI16<_op, (outs CPU16Regs:$rx), (ins CPU16Regs:$rx_, simm16:$imm), 75 !strconcat(asmstr, "\t$rx, $imm\t# 16 bit inst"), [], itin> { 76 let Constraints = "$rx_ = $rx"; 77} 78 79class FRI16_B_ins<bits<5> _op, string asmstr, 80 InstrItinClass itin>: 81 FRI16<_op, (outs), (ins CPU16Regs:$rx, brtarget:$imm), 82 !strconcat(asmstr, "\t$rx, $imm # 16 bit inst"), [], itin>; 83// 84// Compare a register and immediate and place result in CC 85// Implicit use of T8 86// 87// EXT-CCRR Instruction format 88// 89class FEXT_CCRXI16_ins<string asmstr>: 90 MipsPseudo16<(outs CPU16Regs:$cc), (ins CPU16Regs:$rx, simm16:$imm), 91 !strconcat(asmstr, "\t$rx, $imm\n\tmove\t$cc, $$t8"), []> { 92 let isCodeGenOnly=1; 93 let usesCustomInserter = 1; 94} 95 96// JAL and JALX instruction format 97// 98class FJAL16_ins<bits<1> _X, string asmstr, 99 InstrItinClass itin>: 100 FJAL16<_X, (outs), (ins simm20:$imm), 101 !strconcat(asmstr, "\t$imm\n\tnop"),[], 102 itin> { 103 let isCodeGenOnly=1; 104} 105// 106// EXT-I instruction format 107// 108class FEXT_I16_ins<bits<5> eop, string asmstr, InstrItinClass itin> : 109 FEXT_I16<eop, (outs), (ins brtarget:$imm16), 110 !strconcat(asmstr, "\t$imm16"),[], itin>; 111 112// 113// EXT-I8 instruction format 114// 115 116class FEXT_I816_ins_base<bits<3> _func, string asmstr, 117 string asmstr2, InstrItinClass itin>: 118 FEXT_I816<_func, (outs), (ins simm16:$imm), !strconcat(asmstr, asmstr2), 119 [], itin>; 120 121class FEXT_I816_ins<bits<3> _func, string asmstr, 122 InstrItinClass itin>: 123 FEXT_I816_ins_base<_func, asmstr, "\t$imm", itin>; 124 125class FEXT_I816_SP_ins<bits<3> _func, string asmstr, 126 InstrItinClass itin>: 127 FEXT_I816_ins_base<_func, asmstr, "\t$$sp, $imm", itin>; 128 129// 130// Assembler formats in alphabetical order. 131// Natural and pseudos are mixed together. 132// 133// Compare two registers and place result in CC 134// Implicit use of T8 135// 136// CC-RR Instruction format 137// 138class FCCRR16_ins<string asmstr> : 139 MipsPseudo16<(outs CPU16Regs:$cc), (ins CPU16Regs:$rx, CPU16Regs:$ry), 140 !strconcat(asmstr, "\t$rx, $ry\n\tmove\t$cc, $$t8"), []> { 141 let isCodeGenOnly=1; 142 let usesCustomInserter = 1; 143} 144 145// 146// EXT-RI instruction format 147// 148 149class FEXT_RI16_ins_base<bits<5> _op, string asmstr, string asmstr2, 150 InstrItinClass itin>: 151 FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins simm16:$imm), 152 !strconcat(asmstr, asmstr2), [], itin>; 153 154class FEXT_RI16_ins<bits<5> _op, string asmstr, 155 InstrItinClass itin>: 156 FEXT_RI16_ins_base<_op, asmstr, "\t$rx, $imm", itin>; 157 158class FEXT_RI16R_ins_base<bits<5> _op, string asmstr, string asmstr2, 159 InstrItinClass itin>: 160 FEXT_RI16<_op, (outs ), (ins CPU16Regs:$rx, simm16:$imm), 161 !strconcat(asmstr, asmstr2), [], itin>; 162 163class FEXT_RI16R_ins<bits<5> _op, string asmstr, 164 InstrItinClass itin>: 165 FEXT_RI16R_ins_base<_op, asmstr, "\t$rx, $imm", itin>; 166 167class FEXT_RI16_PC_ins<bits<5> _op, string asmstr, InstrItinClass itin>: 168 FEXT_RI16_ins_base<_op, asmstr, "\t$rx, $$pc, $imm", itin>; 169 170class FEXT_RI16_B_ins<bits<5> _op, string asmstr, 171 InstrItinClass itin>: 172 FEXT_RI16<_op, (outs), (ins CPU16Regs:$rx, brtarget:$imm), 173 !strconcat(asmstr, "\t$rx, $imm"), [], itin>; 174 175class FEXT_2RI16_ins<bits<5> _op, string asmstr, 176 InstrItinClass itin>: 177 FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPU16Regs:$rx_, simm16:$imm), 178 !strconcat(asmstr, "\t$rx, $imm"), [], itin> { 179 let Constraints = "$rx_ = $rx"; 180} 181 182 183// this has an explicit sp argument that we ignore to work around a problem 184// in the compiler 185class FEXT_RI16_SP_explicit_ins<bits<5> _op, string asmstr, 186 InstrItinClass itin>: 187 FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPUSPReg:$ry, simm16:$imm), 188 !strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin>; 189 190class FEXT_RI16_SP_Store_explicit_ins<bits<5> _op, string asmstr, 191 InstrItinClass itin>: 192 FEXT_RI16<_op, (outs), (ins CPU16Regs:$rx, CPUSPReg:$ry, simm16:$imm), 193 !strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin>; 194 195// 196// EXT-RRI instruction format 197// 198 199class FEXT_RRI16_mem_ins<bits<5> op, string asmstr, Operand MemOpnd, 200 InstrItinClass itin>: 201 FEXT_RRI16<op, (outs CPU16Regs:$ry), (ins MemOpnd:$addr), 202 !strconcat(asmstr, "\t$ry, $addr"), [], itin>; 203 204class FEXT_RRI16_mem2_ins<bits<5> op, string asmstr, Operand MemOpnd, 205 InstrItinClass itin>: 206 FEXT_RRI16<op, (outs ), (ins CPU16Regs:$ry, MemOpnd:$addr), 207 !strconcat(asmstr, "\t$ry, $addr"), [], itin>; 208 209// 210// 211// EXT-RRI-A instruction format 212// 213 214class FEXT_RRI_A16_mem_ins<bits<1> op, string asmstr, Operand MemOpnd, 215 InstrItinClass itin>: 216 FEXT_RRI_A16<op, (outs CPU16Regs:$ry), (ins MemOpnd:$addr), 217 !strconcat(asmstr, "\t$ry, $addr"), [], itin>; 218 219// 220// EXT-SHIFT instruction format 221// 222class FEXT_SHIFT16_ins<bits<2> _f, string asmstr, InstrItinClass itin>: 223 FEXT_SHIFT16<_f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry, uimm5:$sa), 224 !strconcat(asmstr, "\t$rx, $ry, $sa"), [], itin>; 225 226// 227// EXT-T8I8 228// 229class FEXT_T8I816_ins<string asmstr, string asmstr2>: 230 MipsPseudo16<(outs), 231 (ins CPU16Regs:$rx, CPU16Regs:$ry, brtarget:$imm), 232 !strconcat(asmstr2, !strconcat("\t$rx, $ry\n\t", 233 !strconcat(asmstr, "\t$imm"))),[]> { 234 let isCodeGenOnly=1; 235 let usesCustomInserter = 1; 236} 237 238// 239// EXT-T8I8I 240// 241class FEXT_T8I8I16_ins<string asmstr, string asmstr2>: 242 MipsPseudo16<(outs), 243 (ins CPU16Regs:$rx, simm16:$imm, brtarget:$targ), 244 !strconcat(asmstr2, !strconcat("\t$rx, $imm\n\t", 245 !strconcat(asmstr, "\t$targ"))), []> { 246 let isCodeGenOnly=1; 247 let usesCustomInserter = 1; 248} 249// 250 251 252// 253// I8_MOVR32 instruction format (used only by the MOVR32 instructio 254// 255class FI8_MOVR3216_ins<string asmstr, InstrItinClass itin>: 256 FI8_MOVR3216<(outs CPU16Regs:$rz), (ins GPR32:$r32), 257 !strconcat(asmstr, "\t$rz, $r32"), [], itin>; 258 259// 260// I8_MOV32R instruction format (used only by MOV32R instruction) 261// 262 263class FI8_MOV32R16_ins<string asmstr, InstrItinClass itin>: 264 FI8_MOV32R16<(outs GPR32:$r32), (ins CPU16Regs:$rz), 265 !strconcat(asmstr, "\t$r32, $rz"), [], itin>; 266 267// 268// This are pseudo formats for multiply 269// This first one can be changed to non pseudo now. 270// 271// MULT 272// 273class FMULT16_ins<string asmstr, InstrItinClass itin> : 274 MipsPseudo16<(outs), (ins CPU16Regs:$rx, CPU16Regs:$ry), 275 !strconcat(asmstr, "\t$rx, $ry"), []>; 276 277// 278// MULT-LO 279// 280class FMULT16_LO_ins<string asmstr, InstrItinClass itin> : 281 MipsPseudo16<(outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry), 282 !strconcat(asmstr, "\t$rx, $ry\n\tmflo\t$rz"), []> { 283 let isCodeGenOnly=1; 284} 285 286// 287// RR-type instruction format 288// 289 290class FRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> : 291 FRR16<f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry), 292 !strconcat(asmstr, "\t$rx, $ry"), [], itin> { 293} 294 295class FRRBreakNull16_ins<string asmstr, InstrItinClass itin> : 296 FRRBreak16<(outs), (ins), asmstr, [], itin> { 297 let Code=0; 298} 299 300class FRR16R_ins<bits<5> f, string asmstr, InstrItinClass itin> : 301 FRR16<f, (outs), (ins CPU16Regs:$rx, CPU16Regs:$ry), 302 !strconcat(asmstr, "\t$rx, $ry"), [], itin> { 303} 304 305class FRRTR16_ins<string asmstr> : 306 MipsPseudo16<(outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry), 307 !strconcat(asmstr, "\t$rx, $ry\n\tmove\t$rz, $$t8"), []> ; 308 309// 310// maybe refactor but need a $zero as a dummy first parameter 311// 312class FRR16_div_ins<bits<5> f, string asmstr, InstrItinClass itin> : 313 FRR16<f, (outs ), (ins CPU16Regs:$rx, CPU16Regs:$ry), 314 !strconcat(asmstr, "\t$$zero, $rx, $ry"), [], itin> ; 315 316class FUnaryRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> : 317 FRR16<f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry), 318 !strconcat(asmstr, "\t$rx, $ry"), [], itin> ; 319 320 321class FRR16_M_ins<bits<5> f, string asmstr, 322 InstrItinClass itin> : 323 FRR16<f, (outs CPU16Regs:$rx), (ins), 324 !strconcat(asmstr, "\t$rx"), [], itin>; 325 326class FRxRxRy16_ins<bits<5> f, string asmstr, 327 InstrItinClass itin> : 328 FRR16<f, (outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry), 329 !strconcat(asmstr, "\t$rz, $ry"), 330 [], itin> { 331 let Constraints = "$rx = $rz"; 332} 333 334let rx=0 in 335class FRR16_JALRC_RA_only_ins<bits<1> nd_, bits<1> l_, 336 string asmstr, InstrItinClass itin>: 337 FRR16_JALRC<nd_, l_, 1, (outs), (ins), !strconcat(asmstr, "\t $$ra"), 338 [], itin> ; 339 340 341class FRR16_JALRC_ins<bits<1> nd, bits<1> l, bits<1> ra, 342 string asmstr, InstrItinClass itin>: 343 FRR16_JALRC<nd, l, ra, (outs), (ins CPU16Regs:$rx), 344 !strconcat(asmstr, "\t $rx"), [], itin> ; 345 346// 347// RRR-type instruction format 348// 349 350class FRRR16_ins<bits<2> _f, string asmstr, InstrItinClass itin> : 351 FRRR16<_f, (outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry), 352 !strconcat(asmstr, "\t$rz, $rx, $ry"), [], itin>; 353 354// 355// These Sel patterns support the generation of conditional move 356// pseudo instructions. 357// 358// The nomenclature uses the components making up the pseudo and may 359// be a bit counter intuitive when compared with the end result we seek. 360// For example using a bqez in the example directly below results in the 361// conditional move being done if the tested register is not zero. 362// I considered in easier to check by keeping the pseudo consistent with 363// it's components but it could have been done differently. 364// 365// The simplest case is when can test and operand directly and do the 366// conditional move based on a simple mips16 conditional 367// branch instruction. 368// for example: 369// if $op == beqz or bnez: 370// 371// $op1 $rt, .+4 372// move $rd, $rs 373// 374// if $op == beqz, then if $rt != 0, then the conditional assignment 375// $rd = $rs is done. 376 377// if $op == bnez, then if $rt == 0, then the conditional assignment 378// $rd = $rs is done. 379// 380// So this pseudo class only has one operand, i.e. op 381// 382class Sel<string op>: 383 MipsPseudo16<(outs CPU16Regs:$rd_), (ins CPU16Regs:$rd, CPU16Regs:$rs, 384 CPU16Regs:$rt), 385 !strconcat(op, "\t$rt, .+4\n\t\n\tmove $rd, $rs"), []> { 386 //let isCodeGenOnly=1; 387 let Constraints = "$rd = $rd_"; 388 let usesCustomInserter = 1; 389} 390 391// 392// The next two instruction classes allow for an operand which tests 393// two operands and returns a value in register T8 and 394//then does a conditional branch based on the value of T8 395// 396 397// op2 can be cmpi or slti/sltiu 398// op1 can bteqz or btnez 399// the operands for op2 are a register and a signed constant 400// 401// $op2 $t, $imm ;test register t and branch conditionally 402// $op1 .+4 ;op1 is a conditional branch 403// move $rd, $rs 404// 405// 406class SeliT<string op1, string op2>: 407 MipsPseudo16<(outs CPU16Regs:$rd_), (ins CPU16Regs:$rd, CPU16Regs:$rs, 408 CPU16Regs:$rl, simm16:$imm), 409 !strconcat(op2, 410 !strconcat("\t$rl, $imm\n\t", 411 !strconcat(op1, "\t.+4\n\tmove $rd, $rs"))), []> { 412 let isCodeGenOnly=1; 413 let Constraints = "$rd = $rd_"; 414 let usesCustomInserter = 1; 415} 416 417// 418// op2 can be cmp or slt/sltu 419// op1 can be bteqz or btnez 420// the operands for op2 are two registers 421// op1 is a conditional branch 422// 423// 424// $op2 $rl, $rr ;test registers rl,rr 425// $op1 .+4 ;op2 is a conditional branch 426// move $rd, $rs 427// 428// 429class SelT<string op1, string op2>: 430 MipsPseudo16<(outs CPU16Regs:$rd_), 431 (ins CPU16Regs:$rd, CPU16Regs:$rs, 432 CPU16Regs:$rl, CPU16Regs:$rr), 433 !strconcat(op2, 434 !strconcat("\t$rl, $rr\n\t", 435 !strconcat(op1, "\t.+4\n\tmove $rd, $rs"))), []> { 436 let isCodeGenOnly=1; 437 let Constraints = "$rd = $rd_"; 438 let usesCustomInserter = 1; 439} 440 441// 442// 32 bit constant 443// 444def imm32: Operand<i32>; 445 446def Constant32: 447 MipsPseudo16<(outs), (ins imm32:$imm), "\t.word $imm", []>; 448 449def LwConstant32: 450 MipsPseudo16<(outs CPU16Regs:$rx), (ins imm32:$imm), 451 "lw\t$rx, 1f\n\tb\t2f\n\t.align\t2\n1: \t.word\t$imm\n2:", []>; 452 453 454// 455// Some general instruction class info 456// 457// 458 459class ArithLogic16Defs<bit isCom=0> { 460 bits<5> shamt = 0; 461 bit isCommutable = isCom; 462 bit isReMaterializable = 1; 463 bit neverHasSideEffects = 1; 464} 465 466class branch16 { 467 bit isBranch = 1; 468 bit isTerminator = 1; 469 bit isBarrier = 1; 470} 471 472class cbranch16 { 473 bit isBranch = 1; 474 bit isTerminator = 1; 475} 476 477class MayLoad { 478 bit mayLoad = 1; 479} 480 481class MayStore { 482 bit mayStore = 1; 483} 484// 485 486 487// Format: ADDIU rx, immediate MIPS16e 488// Purpose: Add Immediate Unsigned Word (2-Operand, Extended) 489// To add a constant to a 32-bit integer. 490// 491def AddiuRxImmX16: FEXT_RI16_ins<0b01001, "addiu", IIAlu>; 492 493def AddiuRxRxImm16: F2RI16_ins<0b01001, "addiu", IIAlu>, 494 ArithLogic16Defs<0> { 495 let AddedComplexity = 5; 496} 497def AddiuRxRxImmX16: FEXT_2RI16_ins<0b01001, "addiu", IIAlu>, 498 ArithLogic16Defs<0> { 499 let isCodeGenOnly = 1; 500} 501 502def AddiuRxRyOffMemX16: 503 FEXT_RRI_A16_mem_ins<0, "addiu", mem16_ea, IIAlu>; 504 505// 506 507// Format: ADDIU rx, pc, immediate MIPS16e 508// Purpose: Add Immediate Unsigned Word (3-Operand, PC-Relative, Extended) 509// To add a constant to the program counter. 510// 511def AddiuRxPcImmX16: FEXT_RI16_PC_ins<0b00001, "addiu", IIAlu>; 512 513// 514// Format: ADDIU sp, immediate MIPS16e 515// Purpose: Add Immediate Unsigned Word (2-Operand, SP-Relative, Extended) 516// To add a constant to the stack pointer. 517// 518def AddiuSpImm16 519 : FI816_SP_ins<0b011, "addiu", IIAlu> { 520 let Defs = [SP]; 521 let Uses = [SP]; 522 let AddedComplexity = 5; 523} 524 525def AddiuSpImmX16 526 : FEXT_I816_SP_ins<0b011, "addiu", IIAlu> { 527 let Defs = [SP]; 528 let Uses = [SP]; 529} 530 531// 532// Format: ADDU rz, rx, ry MIPS16e 533// Purpose: Add Unsigned Word (3-Operand) 534// To add 32-bit integers. 535// 536 537def AdduRxRyRz16: FRRR16_ins<01, "addu", IIAlu>, ArithLogic16Defs<1>; 538 539// 540// Format: AND rx, ry MIPS16e 541// Purpose: AND 542// To do a bitwise logical AND. 543 544def AndRxRxRy16: FRxRxRy16_ins<0b01100, "and", IIAlu>, ArithLogic16Defs<1>; 545 546 547// 548// Format: BEQZ rx, offset MIPS16e 549// Purpose: Branch on Equal to Zero 550// To test a GPR then do a PC-relative conditional branch. 551// 552def BeqzRxImm16: FRI16_B_ins<0b00100, "beqz", IIAlu>, cbranch16; 553 554 555// 556// Format: BEQZ rx, offset MIPS16e 557// Purpose: Branch on Equal to Zero (Extended) 558// To test a GPR then do a PC-relative conditional branch. 559// 560def BeqzRxImmX16: FEXT_RI16_B_ins<0b00100, "beqz", IIAlu>, cbranch16; 561 562// Format: B offset MIPS16e 563// Purpose: Unconditional Branch 564// To do an unconditional PC-relative branch. 565// 566def BimmX16: FEXT_I16_ins<0b00010, "b", IIAlu>, branch16; 567 568// 569// Format: BNEZ rx, offset MIPS16e 570// Purpose: Branch on Not Equal to Zero 571// To test a GPR then do a PC-relative conditional branch. 572// 573def BnezRxImm16: FRI16_B_ins<0b00101, "bnez", IIAlu>, cbranch16; 574 575// 576// Format: BNEZ rx, offset MIPS16e 577// Purpose: Branch on Not Equal to Zero (Extended) 578// To test a GPR then do a PC-relative conditional branch. 579// 580def BnezRxImmX16: FEXT_RI16_B_ins<0b00101, "bnez", IIAlu>, cbranch16; 581 582 583// 584//Format: BREAK immediate 585// Purpose: Breakpoint 586// To cause a Breakpoint exception. 587 588def Break16: FRRBreakNull16_ins<"break 0", NoItinerary>; 589// 590// Format: BTEQZ offset MIPS16e 591// Purpose: Branch on T Equal to Zero (Extended) 592// To test special register T then do a PC-relative conditional branch. 593// 594def BteqzX16: FEXT_I816_ins<0b000, "bteqz", IIAlu>, cbranch16 { 595 let Uses = [T8]; 596} 597 598def BteqzT8CmpX16: FEXT_T8I816_ins<"bteqz", "cmp">, cbranch16; 599 600def BteqzT8CmpiX16: FEXT_T8I8I16_ins<"bteqz", "cmpi">, 601 cbranch16; 602 603def BteqzT8SltX16: FEXT_T8I816_ins<"bteqz", "slt">, cbranch16; 604 605def BteqzT8SltuX16: FEXT_T8I816_ins<"bteqz", "sltu">, cbranch16; 606 607def BteqzT8SltiX16: FEXT_T8I8I16_ins<"bteqz", "slti">, cbranch16; 608 609def BteqzT8SltiuX16: FEXT_T8I8I16_ins<"bteqz", "sltiu">, 610 cbranch16; 611 612// 613// Format: BTNEZ offset MIPS16e 614// Purpose: Branch on T Not Equal to Zero (Extended) 615// To test special register T then do a PC-relative conditional branch. 616// 617def BtnezX16: FEXT_I816_ins<0b001, "btnez", IIAlu> ,cbranch16 { 618 let Uses = [T8]; 619} 620 621def BtnezT8CmpX16: FEXT_T8I816_ins<"btnez", "cmp">, cbranch16; 622 623def BtnezT8CmpiX16: FEXT_T8I8I16_ins<"btnez", "cmpi">, cbranch16; 624 625def BtnezT8SltX16: FEXT_T8I816_ins<"btnez", "slt">, cbranch16; 626 627def BtnezT8SltuX16: FEXT_T8I816_ins<"btnez", "sltu">, cbranch16; 628 629def BtnezT8SltiX16: FEXT_T8I8I16_ins<"btnez", "slti">, cbranch16; 630 631def BtnezT8SltiuX16: FEXT_T8I8I16_ins<"btnez", "sltiu">, 632 cbranch16; 633 634// 635// Format: CMP rx, ry MIPS16e 636// Purpose: Compare 637// To compare the contents of two GPRs. 638// 639def CmpRxRy16: FRR16R_ins<0b01010, "cmp", IIAlu> { 640 let Defs = [T8]; 641} 642 643// 644// Format: CMPI rx, immediate MIPS16e 645// Purpose: Compare Immediate 646// To compare a constant with the contents of a GPR. 647// 648def CmpiRxImm16: FRI16R_ins<0b01110, "cmpi", IIAlu> { 649 let Defs = [T8]; 650} 651 652// 653// Format: CMPI rx, immediate MIPS16e 654// Purpose: Compare Immediate (Extended) 655// To compare a constant with the contents of a GPR. 656// 657def CmpiRxImmX16: FEXT_RI16R_ins<0b01110, "cmpi", IIAlu> { 658 let Defs = [T8]; 659} 660 661 662// 663// Format: DIV rx, ry MIPS16e 664// Purpose: Divide Word 665// To divide 32-bit signed integers. 666// 667def DivRxRy16: FRR16_div_ins<0b11010, "div", IIAlu> { 668 let Defs = [HI0, LO0]; 669} 670 671// 672// Format: DIVU rx, ry MIPS16e 673// Purpose: Divide Unsigned Word 674// To divide 32-bit unsigned integers. 675// 676def DivuRxRy16: FRR16_div_ins<0b11011, "divu", IIAlu> { 677 let Defs = [HI0, LO0]; 678} 679// 680// Format: JAL target MIPS16e 681// Purpose: Jump and Link 682// To execute a procedure call within the current 256 MB-aligned 683// region and preserve the current ISA. 684// 685 686def Jal16 : FJAL16_ins<0b0, "jal", IIAlu> { 687 let hasDelaySlot = 0; // not true, but we add the nop for now 688 let isCall=1; 689} 690 691// 692// Format: JR ra MIPS16e 693// Purpose: Jump Register Through Register ra 694// To execute a branch to the instruction address in the return 695// address register. 696// 697 698def JrRa16: FRR16_JALRC_RA_only_ins<0, 0, "jr", IIAlu> { 699 let isBranch = 1; 700 let isIndirectBranch = 1; 701 let hasDelaySlot = 1; 702 let isTerminator=1; 703 let isBarrier=1; 704} 705 706def JrcRa16: FRR16_JALRC_RA_only_ins<1, 1, "jrc", IIAlu> { 707 let isBranch = 1; 708 let isIndirectBranch = 1; 709 let isTerminator=1; 710 let isBarrier=1; 711} 712 713def JrcRx16: FRR16_JALRC_ins<1, 1, 0, "jrc", IIAlu> { 714 let isBranch = 1; 715 let isIndirectBranch = 1; 716 let isTerminator=1; 717 let isBarrier=1; 718} 719// 720// Format: LB ry, offset(rx) MIPS16e 721// Purpose: Load Byte (Extended) 722// To load a byte from memory as a signed value. 723// 724def LbRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10011, "lb", mem16, IILoad>, MayLoad{ 725 let isCodeGenOnly = 1; 726} 727 728// 729// Format: LBU ry, offset(rx) MIPS16e 730// Purpose: Load Byte Unsigned (Extended) 731// To load a byte from memory as a unsigned value. 732// 733def LbuRxRyOffMemX16: 734 FEXT_RRI16_mem_ins<0b10100, "lbu", mem16, IILoad>, MayLoad { 735 let isCodeGenOnly = 1; 736} 737 738// 739// Format: LH ry, offset(rx) MIPS16e 740// Purpose: Load Halfword signed (Extended) 741// To load a halfword from memory as a signed value. 742// 743def LhRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10100, "lh", mem16, IILoad>, MayLoad{ 744 let isCodeGenOnly = 1; 745} 746 747// 748// Format: LHU ry, offset(rx) MIPS16e 749// Purpose: Load Halfword unsigned (Extended) 750// To load a halfword from memory as an unsigned value. 751// 752def LhuRxRyOffMemX16: 753 FEXT_RRI16_mem_ins<0b10100, "lhu", mem16, IILoad>, MayLoad { 754 let isCodeGenOnly = 1; 755} 756 757// 758// Format: LI rx, immediate MIPS16e 759// Purpose: Load Immediate 760// To load a constant into a GPR. 761// 762def LiRxImm16: FRI16_ins<0b01101, "li", IIAlu>; 763 764// 765// Format: LI rx, immediate MIPS16e 766// Purpose: Load Immediate (Extended) 767// To load a constant into a GPR. 768// 769def LiRxImmX16: FEXT_RI16_ins<0b01101, "li", IIAlu>; 770 771// 772// Format: LW ry, offset(rx) MIPS16e 773// Purpose: Load Word (Extended) 774// To load a word from memory as a signed value. 775// 776def LwRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10011, "lw", mem16, IILoad>, MayLoad{ 777 let isCodeGenOnly = 1; 778} 779 780// Format: LW rx, offset(sp) MIPS16e 781// Purpose: Load Word (SP-Relative, Extended) 782// To load an SP-relative word from memory as a signed value. 783// 784def LwRxSpImmX16: FEXT_RI16_SP_explicit_ins<0b10110, "lw", IILoad>, MayLoad{ 785 let Uses = [SP]; 786} 787 788// 789// Format: MOVE r32, rz MIPS16e 790// Purpose: Move 791// To move the contents of a GPR to a GPR. 792// 793def Move32R16: FI8_MOV32R16_ins<"move", IIAlu>; 794 795// 796// Format: MOVE ry, r32 MIPS16e 797//Purpose: Move 798// To move the contents of a GPR to a GPR. 799// 800def MoveR3216: FI8_MOVR3216_ins<"move", IIAlu>; 801 802// 803// Format: MFHI rx MIPS16e 804// Purpose: Move From HI Register 805// To copy the special purpose HI register to a GPR. 806// 807def Mfhi16: FRR16_M_ins<0b10000, "mfhi", IIAlu> { 808 let Uses = [HI0]; 809 let neverHasSideEffects = 1; 810} 811 812// 813// Format: MFLO rx MIPS16e 814// Purpose: Move From LO Register 815// To copy the special purpose LO register to a GPR. 816// 817def Mflo16: FRR16_M_ins<0b10010, "mflo", IIAlu> { 818 let Uses = [LO0]; 819 let neverHasSideEffects = 1; 820} 821 822// 823// Pseudo Instruction for mult 824// 825def MultRxRy16: FMULT16_ins<"mult", IIAlu> { 826 let isCommutable = 1; 827 let neverHasSideEffects = 1; 828 let Defs = [HI0, LO0]; 829} 830 831def MultuRxRy16: FMULT16_ins<"multu", IIAlu> { 832 let isCommutable = 1; 833 let neverHasSideEffects = 1; 834 let Defs = [HI0, LO0]; 835} 836 837// 838// Format: MULT rx, ry MIPS16e 839// Purpose: Multiply Word 840// To multiply 32-bit signed integers. 841// 842def MultRxRyRz16: FMULT16_LO_ins<"mult", IIAlu> { 843 let isCommutable = 1; 844 let neverHasSideEffects = 1; 845 let Defs = [HI0, LO0]; 846} 847 848// 849// Format: MULTU rx, ry MIPS16e 850// Purpose: Multiply Unsigned Word 851// To multiply 32-bit unsigned integers. 852// 853def MultuRxRyRz16: FMULT16_LO_ins<"multu", IIAlu> { 854 let isCommutable = 1; 855 let neverHasSideEffects = 1; 856 let Defs = [HI0, LO0]; 857} 858 859// 860// Format: NEG rx, ry MIPS16e 861// Purpose: Negate 862// To negate an integer value. 863// 864def NegRxRy16: FUnaryRR16_ins<0b11101, "neg", IIAlu>; 865 866// 867// Format: NOT rx, ry MIPS16e 868// Purpose: Not 869// To complement an integer value 870// 871def NotRxRy16: FUnaryRR16_ins<0b01111, "not", IIAlu>; 872 873// 874// Format: OR rx, ry MIPS16e 875// Purpose: Or 876// To do a bitwise logical OR. 877// 878def OrRxRxRy16: FRxRxRy16_ins<0b01101, "or", IIAlu>, ArithLogic16Defs<1>; 879 880// 881// Format: RESTORE {ra,}{s0/s1/s0-1,}{framesize} 882// (All args are optional) MIPS16e 883// Purpose: Restore Registers and Deallocate Stack Frame 884// To deallocate a stack frame before exit from a subroutine, 885// restoring return address and static registers, and adjusting 886// stack 887// 888 889// fixed form for restoring RA and the frame 890// for direct object emitter, encoding needs to be adjusted for the 891// frame size 892// 893let ra=1, s=0,s0=1,s1=1 in 894def RestoreRaF16: 895 FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), 896 "restore\t$$ra, $$s0, $$s1, $$s2, $frame_size", [], IILoad >, MayLoad { 897 let isCodeGenOnly = 1; 898 let Defs = [S0, S1, S2, RA, SP]; 899 let Uses = [SP]; 900} 901 902// Use Restore to increment SP since SP is not a Mip 16 register, this 903// is an easy way to do that which does not require a register. 904// 905let ra=0, s=0,s0=0,s1=0 in 906def RestoreIncSpF16: 907 FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), 908 "restore\t$frame_size", [], IILoad >, MayLoad { 909 let isCodeGenOnly = 1; 910 let Defs = [SP]; 911 let Uses = [SP]; 912} 913 914// 915// Format: SAVE {ra,}{s0/s1/s0-1,}{framesize} (All arguments are optional) 916// MIPS16e 917// Purpose: Save Registers and Set Up Stack Frame 918// To set up a stack frame on entry to a subroutine, 919// saving return address and static registers, and adjusting stack 920// 921let ra=1, s=1,s0=1,s1=1 in 922def SaveRaF16: 923 FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), 924 "save\t$$ra, $$s0, $$s1, $$s2, $frame_size", [], IIStore >, MayStore { 925 let isCodeGenOnly = 1; 926 let Uses = [RA, SP, S0, S1, S2]; 927 let Defs = [SP]; 928} 929 930// 931// Use Save to decrement the SP by a constant since SP is not 932// a Mips16 register. 933// 934let ra=0, s=0,s0=0,s1=0 in 935def SaveDecSpF16: 936 FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), 937 "save\t$frame_size", [], IIStore >, MayStore { 938 let isCodeGenOnly = 1; 939 let Uses = [SP]; 940 let Defs = [SP]; 941} 942// 943// Format: SB ry, offset(rx) MIPS16e 944// Purpose: Store Byte (Extended) 945// To store a byte to memory. 946// 947def SbRxRyOffMemX16: 948 FEXT_RRI16_mem2_ins<0b11000, "sb", mem16, IIStore>, MayStore; 949 950// 951// The Sel(T) instructions are pseudos 952// T means that they use T8 implicitly. 953// 954// 955// Format: SelBeqZ rd, rs, rt 956// Purpose: if rt==0, do nothing 957// else rs = rt 958// 959def SelBeqZ: Sel<"beqz">; 960 961// 962// Format: SelTBteqZCmp rd, rs, rl, rr 963// Purpose: b = Cmp rl, rr. 964// If b==0 then do nothing. 965// if b!=0 then rd = rs 966// 967def SelTBteqZCmp: SelT<"bteqz", "cmp">; 968 969// 970// Format: SelTBteqZCmpi rd, rs, rl, rr 971// Purpose: b = Cmpi rl, imm. 972// If b==0 then do nothing. 973// if b!=0 then rd = rs 974// 975def SelTBteqZCmpi: SeliT<"bteqz", "cmpi">; 976 977// 978// Format: SelTBteqZSlt rd, rs, rl, rr 979// Purpose: b = Slt rl, rr. 980// If b==0 then do nothing. 981// if b!=0 then rd = rs 982// 983def SelTBteqZSlt: SelT<"bteqz", "slt">; 984 985// 986// Format: SelTBteqZSlti rd, rs, rl, rr 987// Purpose: b = Slti rl, imm. 988// If b==0 then do nothing. 989// if b!=0 then rd = rs 990// 991def SelTBteqZSlti: SeliT<"bteqz", "slti">; 992 993// 994// Format: SelTBteqZSltu rd, rs, rl, rr 995// Purpose: b = Sltu rl, rr. 996// If b==0 then do nothing. 997// if b!=0 then rd = rs 998// 999def SelTBteqZSltu: SelT<"bteqz", "sltu">; 1000 1001// 1002// Format: SelTBteqZSltiu rd, rs, rl, rr 1003// Purpose: b = Sltiu rl, imm. 1004// If b==0 then do nothing. 1005// if b!=0 then rd = rs 1006// 1007def SelTBteqZSltiu: SeliT<"bteqz", "sltiu">; 1008 1009// 1010// Format: SelBnez rd, rs, rt 1011// Purpose: if rt!=0, do nothing 1012// else rs = rt 1013// 1014def SelBneZ: Sel<"bnez">; 1015 1016// 1017// Format: SelTBtneZCmp rd, rs, rl, rr 1018// Purpose: b = Cmp rl, rr. 1019// If b!=0 then do nothing. 1020// if b0=0 then rd = rs 1021// 1022def SelTBtneZCmp: SelT<"btnez", "cmp">; 1023 1024// 1025// Format: SelTBtnezCmpi rd, rs, rl, rr 1026// Purpose: b = Cmpi rl, imm. 1027// If b!=0 then do nothing. 1028// if b==0 then rd = rs 1029// 1030def SelTBtneZCmpi: SeliT<"btnez", "cmpi">; 1031 1032// 1033// Format: SelTBtneZSlt rd, rs, rl, rr 1034// Purpose: b = Slt rl, rr. 1035// If b!=0 then do nothing. 1036// if b==0 then rd = rs 1037// 1038def SelTBtneZSlt: SelT<"btnez", "slt">; 1039 1040// 1041// Format: SelTBtneZSlti rd, rs, rl, rr 1042// Purpose: b = Slti rl, imm. 1043// If b!=0 then do nothing. 1044// if b==0 then rd = rs 1045// 1046def SelTBtneZSlti: SeliT<"btnez", "slti">; 1047 1048// 1049// Format: SelTBtneZSltu rd, rs, rl, rr 1050// Purpose: b = Sltu rl, rr. 1051// If b!=0 then do nothing. 1052// if b==0 then rd = rs 1053// 1054def SelTBtneZSltu: SelT<"btnez", "sltu">; 1055 1056// 1057// Format: SelTBtneZSltiu rd, rs, rl, rr 1058// Purpose: b = Slti rl, imm. 1059// If b!=0 then do nothing. 1060// if b==0 then rd = rs 1061// 1062def SelTBtneZSltiu: SeliT<"btnez", "sltiu">; 1063// 1064// 1065// Format: SH ry, offset(rx) MIPS16e 1066// Purpose: Store Halfword (Extended) 1067// To store a halfword to memory. 1068// 1069def ShRxRyOffMemX16: 1070 FEXT_RRI16_mem2_ins<0b11001, "sh", mem16, IIStore>, MayStore; 1071 1072// 1073// Format: SLL rx, ry, sa MIPS16e 1074// Purpose: Shift Word Left Logical (Extended) 1075// To execute a left-shift of a word by a fixed number of bits—0 to 31 bits. 1076// 1077def SllX16: FEXT_SHIFT16_ins<0b00, "sll", IIAlu>; 1078 1079// 1080// Format: SLLV ry, rx MIPS16e 1081// Purpose: Shift Word Left Logical Variable 1082// To execute a left-shift of a word by a variable number of bits. 1083// 1084def SllvRxRy16 : FRxRxRy16_ins<0b00100, "sllv", IIAlu>; 1085 1086// Format: SLTI rx, immediate MIPS16e 1087// Purpose: Set on Less Than Immediate 1088// To record the result of a less-than comparison with a constant. 1089// 1090// 1091def SltiRxImm16: FRI16R_ins<0b01010, "slti", IIAlu> { 1092 let Defs = [T8]; 1093} 1094 1095// 1096// Format: SLTI rx, immediate MIPS16e 1097// Purpose: Set on Less Than Immediate (Extended) 1098// To record the result of a less-than comparison with a constant. 1099// 1100// 1101def SltiRxImmX16: FEXT_RI16R_ins<0b01010, "slti", IIAlu> { 1102 let Defs = [T8]; 1103} 1104 1105def SltiCCRxImmX16: FEXT_CCRXI16_ins<"slti">; 1106 1107// Format: SLTIU rx, immediate MIPS16e 1108// Purpose: Set on Less Than Immediate Unsigned 1109// To record the result of a less-than comparison with a constant. 1110// 1111// 1112def SltiuRxImm16: FRI16R_ins<0b01011, "sltiu", IIAlu> { 1113 let Defs = [T8]; 1114} 1115 1116// 1117// Format: SLTI rx, immediate MIPS16e 1118// Purpose: Set on Less Than Immediate Unsigned (Extended) 1119// To record the result of a less-than comparison with a constant. 1120// 1121// 1122def SltiuRxImmX16: FEXT_RI16R_ins<0b01011, "sltiu", IIAlu> { 1123 let Defs = [T8]; 1124} 1125// 1126// Format: SLTIU rx, immediate MIPS16e 1127// Purpose: Set on Less Than Immediate Unsigned (Extended) 1128// To record the result of a less-than comparison with a constant. 1129// 1130def SltiuCCRxImmX16: FEXT_CCRXI16_ins<"sltiu">; 1131 1132// 1133// Format: SLT rx, ry MIPS16e 1134// Purpose: Set on Less Than 1135// To record the result of a less-than comparison. 1136// 1137def SltRxRy16: FRR16R_ins<0b00010, "slt", IIAlu>{ 1138 let Defs = [T8]; 1139} 1140 1141def SltCCRxRy16: FCCRR16_ins<"slt">; 1142 1143// Format: SLTU rx, ry MIPS16e 1144// Purpose: Set on Less Than Unsigned 1145// To record the result of an unsigned less-than comparison. 1146// 1147def SltuRxRy16: FRR16R_ins<0b00011, "sltu", IIAlu>{ 1148 let Defs = [T8]; 1149} 1150 1151def SltuRxRyRz16: FRRTR16_ins<"sltu"> { 1152 let isCodeGenOnly=1; 1153 let Defs = [T8]; 1154} 1155 1156 1157def SltuCCRxRy16: FCCRR16_ins<"sltu">; 1158// 1159// Format: SRAV ry, rx MIPS16e 1160// Purpose: Shift Word Right Arithmetic Variable 1161// To execute an arithmetic right-shift of a word by a variable 1162// number of bits. 1163// 1164def SravRxRy16: FRxRxRy16_ins<0b00111, "srav", IIAlu>; 1165 1166 1167// 1168// Format: SRA rx, ry, sa MIPS16e 1169// Purpose: Shift Word Right Arithmetic (Extended) 1170// To execute an arithmetic right-shift of a word by a fixed 1171// number of bits—1 to 8 bits. 1172// 1173def SraX16: FEXT_SHIFT16_ins<0b11, "sra", IIAlu>; 1174 1175 1176// 1177// Format: SRLV ry, rx MIPS16e 1178// Purpose: Shift Word Right Logical Variable 1179// To execute a logical right-shift of a word by a variable 1180// number of bits. 1181// 1182def SrlvRxRy16: FRxRxRy16_ins<0b00110, "srlv", IIAlu>; 1183 1184 1185// 1186// Format: SRL rx, ry, sa MIPS16e 1187// Purpose: Shift Word Right Logical (Extended) 1188// To execute a logical right-shift of a word by a fixed 1189// number of bits—1 to 31 bits. 1190// 1191def SrlX16: FEXT_SHIFT16_ins<0b10, "srl", IIAlu>; 1192 1193// 1194// Format: SUBU rz, rx, ry MIPS16e 1195// Purpose: Subtract Unsigned Word 1196// To subtract 32-bit integers 1197// 1198def SubuRxRyRz16: FRRR16_ins<0b11, "subu", IIAlu>, ArithLogic16Defs<0>; 1199 1200// 1201// Format: SW ry, offset(rx) MIPS16e 1202// Purpose: Store Word (Extended) 1203// To store a word to memory. 1204// 1205def SwRxRyOffMemX16: 1206 FEXT_RRI16_mem2_ins<0b11011, "sw", mem16, IIStore>, MayStore; 1207 1208// 1209// Format: SW rx, offset(sp) MIPS16e 1210// Purpose: Store Word rx (SP-Relative) 1211// To store an SP-relative word to memory. 1212// 1213def SwRxSpImmX16: FEXT_RI16_SP_Store_explicit_ins 1214 <0b11010, "sw", IIStore>, MayStore; 1215 1216// 1217// 1218// Format: XOR rx, ry MIPS16e 1219// Purpose: Xor 1220// To do a bitwise logical XOR. 1221// 1222def XorRxRxRy16: FRxRxRy16_ins<0b01110, "xor", IIAlu>, ArithLogic16Defs<1>; 1223 1224class Mips16Pat<dag pattern, dag result> : Pat<pattern, result> { 1225 let Predicates = [InMips16Mode]; 1226} 1227 1228// Unary Arith/Logic 1229// 1230class ArithLogicU_pat<PatFrag OpNode, Instruction I> : 1231 Mips16Pat<(OpNode CPU16Regs:$r), 1232 (I CPU16Regs:$r)>; 1233 1234def: ArithLogicU_pat<not, NotRxRy16>; 1235def: ArithLogicU_pat<ineg, NegRxRy16>; 1236 1237class ArithLogic16_pat<SDNode OpNode, Instruction I> : 1238 Mips16Pat<(OpNode CPU16Regs:$l, CPU16Regs:$r), 1239 (I CPU16Regs:$l, CPU16Regs:$r)>; 1240 1241def: ArithLogic16_pat<add, AdduRxRyRz16>; 1242def: ArithLogic16_pat<and, AndRxRxRy16>; 1243def: ArithLogic16_pat<mul, MultRxRyRz16>; 1244def: ArithLogic16_pat<or, OrRxRxRy16>; 1245def: ArithLogic16_pat<sub, SubuRxRyRz16>; 1246def: ArithLogic16_pat<xor, XorRxRxRy16>; 1247 1248// Arithmetic and logical instructions with 2 register operands. 1249 1250class ArithLogicI16_pat<SDNode OpNode, PatFrag imm_type, Instruction I> : 1251 Mips16Pat<(OpNode CPU16Regs:$in, imm_type:$imm), 1252 (I CPU16Regs:$in, imm_type:$imm)>; 1253 1254def: ArithLogicI16_pat<add, immSExt8, AddiuRxRxImm16>; 1255def: ArithLogicI16_pat<add, immSExt16, AddiuRxRxImmX16>; 1256def: ArithLogicI16_pat<shl, immZExt5, SllX16>; 1257def: ArithLogicI16_pat<srl, immZExt5, SrlX16>; 1258def: ArithLogicI16_pat<sra, immZExt5, SraX16>; 1259 1260class shift_rotate_reg16_pat<SDNode OpNode, Instruction I> : 1261 Mips16Pat<(OpNode CPU16Regs:$r, CPU16Regs:$ra), 1262 (I CPU16Regs:$r, CPU16Regs:$ra)>; 1263 1264def: shift_rotate_reg16_pat<shl, SllvRxRy16>; 1265def: shift_rotate_reg16_pat<sra, SravRxRy16>; 1266def: shift_rotate_reg16_pat<srl, SrlvRxRy16>; 1267 1268class LoadM16_pat<PatFrag OpNode, Instruction I> : 1269 Mips16Pat<(OpNode addr16:$addr), (I addr16:$addr)>; 1270 1271def: LoadM16_pat<sextloadi8, LbRxRyOffMemX16>; 1272def: LoadM16_pat<zextloadi8, LbuRxRyOffMemX16>; 1273def: LoadM16_pat<sextloadi16, LhRxRyOffMemX16>; 1274def: LoadM16_pat<zextloadi16, LhuRxRyOffMemX16>; 1275def: LoadM16_pat<load, LwRxRyOffMemX16>; 1276 1277class StoreM16_pat<PatFrag OpNode, Instruction I> : 1278 Mips16Pat<(OpNode CPU16Regs:$r, addr16:$addr), 1279 (I CPU16Regs:$r, addr16:$addr)>; 1280 1281def: StoreM16_pat<truncstorei8, SbRxRyOffMemX16>; 1282def: StoreM16_pat<truncstorei16, ShRxRyOffMemX16>; 1283def: StoreM16_pat<store, SwRxRyOffMemX16>; 1284 1285// Unconditional branch 1286class UncondBranch16_pat<SDNode OpNode, Instruction I>: 1287 Mips16Pat<(OpNode bb:$imm16), (I bb:$imm16)> { 1288 let Predicates = [InMips16Mode]; 1289 } 1290 1291def : Mips16Pat<(MipsJmpLink (i32 tglobaladdr:$dst)), 1292 (Jal16 tglobaladdr:$dst)>; 1293 1294def : Mips16Pat<(MipsJmpLink (i32 texternalsym:$dst)), 1295 (Jal16 texternalsym:$dst)>; 1296 1297// Indirect branch 1298def: Mips16Pat< 1299 (brind CPU16Regs:$rs), 1300 (JrcRx16 CPU16Regs:$rs)>; 1301 1302// Jump and Link (Call) 1303let isCall=1, hasDelaySlot=0 in 1304def JumpLinkReg16: 1305 FRR16_JALRC<0, 0, 0, (outs), (ins CPU16Regs:$rs), 1306 "jalrc \t$rs", [(MipsJmpLink CPU16Regs:$rs)], IIBranch>; 1307 1308// Mips16 pseudos 1309let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1, 1310 hasExtraSrcRegAllocReq = 1 in 1311def RetRA16 : MipsPseudo16<(outs), (ins), "", [(MipsRet)]>; 1312 1313 1314// setcc patterns 1315 1316class SetCC_R16<PatFrag cond_op, Instruction I>: 1317 Mips16Pat<(cond_op CPU16Regs:$rx, CPU16Regs:$ry), 1318 (I CPU16Regs:$rx, CPU16Regs:$ry)>; 1319 1320class SetCC_I16<PatFrag cond_op, PatLeaf imm_type, Instruction I>: 1321 Mips16Pat<(cond_op CPU16Regs:$rx, imm_type:$imm16), 1322 (I CPU16Regs:$rx, imm_type:$imm16)>; 1323 1324 1325def: Mips16Pat<(i32 addr16:$addr), 1326 (AddiuRxRyOffMemX16 addr16:$addr)>; 1327 1328 1329// Large (>16 bit) immediate loads 1330def : Mips16Pat<(i32 imm:$imm), 1331 (OrRxRxRy16 (SllX16 (LiRxImmX16 (HI16 imm:$imm)), 16), 1332 (LiRxImmX16 (LO16 imm:$imm)))>; 1333 1334// Carry MipsPatterns 1335def : Mips16Pat<(subc CPU16Regs:$lhs, CPU16Regs:$rhs), 1336 (SubuRxRyRz16 CPU16Regs:$lhs, CPU16Regs:$rhs)>; 1337def : Mips16Pat<(addc CPU16Regs:$lhs, CPU16Regs:$rhs), 1338 (AdduRxRyRz16 CPU16Regs:$lhs, CPU16Regs:$rhs)>; 1339def : Mips16Pat<(addc CPU16Regs:$src, immSExt16:$imm), 1340 (AddiuRxRxImmX16 CPU16Regs:$src, imm:$imm)>; 1341 1342// 1343// Some branch conditional patterns are not generated by llvm at this time. 1344// Some are for seemingly arbitrary reasons not used: i.e. with signed number 1345// comparison they are used and for unsigned a different pattern is used. 1346// I am pushing upstream from the full mips16 port and it seemed that I needed 1347// these earlier and the mips32 port has these but now I cannot create test 1348// cases that use these patterns. While I sort this all out I will leave these 1349// extra patterns commented out and if I can be sure they are really not used, 1350// I will delete the code. I don't want to check the code in uncommented without 1351// a valid test case. In some cases, the compiler is generating patterns with 1352// setcc instead and earlier I had implemented setcc first so may have masked 1353// the problem. The setcc variants are suboptimal for mips16 so I may wantto 1354// figure out how to enable the brcond patterns or else possibly new 1355// combinations of of brcond and setcc. 1356// 1357// 1358// bcond-seteq 1359// 1360def: Mips16Pat 1361 <(brcond (i32 (seteq CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16), 1362 (BteqzT8CmpX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16) 1363 >; 1364 1365 1366def: Mips16Pat 1367 <(brcond (i32 (seteq CPU16Regs:$rx, immZExt16:$imm)), bb:$targ16), 1368 (BteqzT8CmpiX16 CPU16Regs:$rx, immSExt16:$imm, bb:$targ16) 1369 >; 1370 1371def: Mips16Pat 1372 <(brcond (i32 (seteq CPU16Regs:$rx, 0)), bb:$targ16), 1373 (BeqzRxImmX16 CPU16Regs:$rx, bb:$targ16) 1374 >; 1375 1376// 1377// bcond-setgt (do we need to have this pair of setlt, setgt??) 1378// 1379def: Mips16Pat 1380 <(brcond (i32 (setgt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16), 1381 (BtnezT8SltX16 CPU16Regs:$ry, CPU16Regs:$rx, bb:$imm16) 1382 >; 1383 1384// 1385// bcond-setge 1386// 1387def: Mips16Pat 1388 <(brcond (i32 (setge CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16), 1389 (BteqzT8SltX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16) 1390 >; 1391 1392// 1393// never called because compiler transforms a >= k to a > (k-1) 1394def: Mips16Pat 1395 <(brcond (i32 (setge CPU16Regs:$rx, immSExt16:$imm)), bb:$imm16), 1396 (BteqzT8SltiX16 CPU16Regs:$rx, immSExt16:$imm, bb:$imm16) 1397 >; 1398 1399// 1400// bcond-setlt 1401// 1402def: Mips16Pat 1403 <(brcond (i32 (setlt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16), 1404 (BtnezT8SltX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16) 1405 >; 1406 1407def: Mips16Pat 1408 <(brcond (i32 (setlt CPU16Regs:$rx, immSExt16:$imm)), bb:$imm16), 1409 (BtnezT8SltiX16 CPU16Regs:$rx, immSExt16:$imm, bb:$imm16) 1410 >; 1411 1412// 1413// bcond-setle 1414// 1415def: Mips16Pat 1416 <(brcond (i32 (setle CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16), 1417 (BteqzT8SltX16 CPU16Regs:$ry, CPU16Regs:$rx, bb:$imm16) 1418 >; 1419 1420// 1421// bcond-setne 1422// 1423def: Mips16Pat 1424 <(brcond (i32 (setne CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16), 1425 (BtnezT8CmpX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16) 1426 >; 1427 1428def: Mips16Pat 1429 <(brcond (i32 (setne CPU16Regs:$rx, immZExt16:$imm)), bb:$targ16), 1430 (BtnezT8CmpiX16 CPU16Regs:$rx, immSExt16:$imm, bb:$targ16) 1431 >; 1432 1433def: Mips16Pat 1434 <(brcond (i32 (setne CPU16Regs:$rx, 0)), bb:$targ16), 1435 (BnezRxImmX16 CPU16Regs:$rx, bb:$targ16) 1436 >; 1437 1438// 1439// This needs to be there but I forget which code will generate it 1440// 1441def: Mips16Pat 1442 <(brcond CPU16Regs:$rx, bb:$targ16), 1443 (BnezRxImmX16 CPU16Regs:$rx, bb:$targ16) 1444 >; 1445 1446// 1447 1448// 1449// bcond-setugt 1450// 1451//def: Mips16Pat 1452// <(brcond (i32 (setugt CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16), 1453// (BtnezT8SltuX16 CPU16Regs:$ry, CPU16Regs:$rx, bb:$imm16) 1454// >; 1455 1456// 1457// bcond-setuge 1458// 1459//def: Mips16Pat 1460// <(brcond (i32 (setuge CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16), 1461// (BteqzT8SltuX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16) 1462// >; 1463 1464 1465// 1466// bcond-setult 1467// 1468//def: Mips16Pat 1469// <(brcond (i32 (setult CPU16Regs:$rx, CPU16Regs:$ry)), bb:$imm16), 1470// (BtnezT8SltuX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16) 1471// >; 1472 1473def: UncondBranch16_pat<br, BimmX16>; 1474 1475// Small immediates 1476def: Mips16Pat<(i32 immSExt16:$in), 1477 (AddiuRxRxImmX16 (Move32R16 ZERO), immSExt16:$in)>; 1478 1479def: Mips16Pat<(i32 immZExt16:$in), (LiRxImmX16 immZExt16:$in)>; 1480 1481// 1482// MipsDivRem 1483// 1484def: Mips16Pat 1485 <(MipsDivRem16 CPU16Regs:$rx, CPU16Regs:$ry), 1486 (DivRxRy16 CPU16Regs:$rx, CPU16Regs:$ry)>; 1487 1488// 1489// MipsDivRemU 1490// 1491def: Mips16Pat 1492 <(MipsDivRemU16 CPU16Regs:$rx, CPU16Regs:$ry), 1493 (DivuRxRy16 CPU16Regs:$rx, CPU16Regs:$ry)>; 1494 1495// signed a,b 1496// x = (a>=b)?x:y 1497// 1498// if !(a < b) x = y 1499// 1500def : Mips16Pat<(select (i32 (setge CPU16Regs:$a, CPU16Regs:$b)), 1501 CPU16Regs:$x, CPU16Regs:$y), 1502 (SelTBteqZSlt CPU16Regs:$x, CPU16Regs:$y, 1503 CPU16Regs:$a, CPU16Regs:$b)>; 1504 1505// signed a,b 1506// x = (a>b)?x:y 1507// 1508// if (b < a) x = y 1509// 1510def : Mips16Pat<(select (i32 (setgt CPU16Regs:$a, CPU16Regs:$b)), 1511 CPU16Regs:$x, CPU16Regs:$y), 1512 (SelTBtneZSlt CPU16Regs:$x, CPU16Regs:$y, 1513 CPU16Regs:$b, CPU16Regs:$a)>; 1514 1515// unsigned a,b 1516// x = (a>=b)?x:y 1517// 1518// if !(a < b) x = y; 1519// 1520def : Mips16Pat< 1521 (select (i32 (setuge CPU16Regs:$a, CPU16Regs:$b)), 1522 CPU16Regs:$x, CPU16Regs:$y), 1523 (SelTBteqZSltu CPU16Regs:$x, CPU16Regs:$y, 1524 CPU16Regs:$a, CPU16Regs:$b)>; 1525 1526// unsigned a,b 1527// x = (a>b)?x:y 1528// 1529// if (b < a) x = y 1530// 1531def : Mips16Pat<(select (i32 (setugt CPU16Regs:$a, CPU16Regs:$b)), 1532 CPU16Regs:$x, CPU16Regs:$y), 1533 (SelTBtneZSltu CPU16Regs:$x, CPU16Regs:$y, 1534 CPU16Regs:$b, CPU16Regs:$a)>; 1535 1536// signed 1537// x = (a >= k)?x:y 1538// due to an llvm optimization, i don't think that this will ever 1539// be used. This is transformed into x = (a > k-1)?x:y 1540// 1541// 1542 1543//def : Mips16Pat< 1544// (select (i32 (setge CPU16Regs:$lhs, immSExt16:$rhs)), 1545// CPU16Regs:$T, CPU16Regs:$F), 1546// (SelTBteqZSlti CPU16Regs:$T, CPU16Regs:$F, 1547// CPU16Regs:$lhs, immSExt16:$rhs)>; 1548 1549//def : Mips16Pat< 1550// (select (i32 (setuge CPU16Regs:$lhs, immSExt16:$rhs)), 1551// CPU16Regs:$T, CPU16Regs:$F), 1552// (SelTBteqZSltiu CPU16Regs:$T, CPU16Regs:$F, 1553// CPU16Regs:$lhs, immSExt16:$rhs)>; 1554 1555// signed 1556// x = (a < k)?x:y 1557// 1558// if !(a < k) x = y; 1559// 1560def : Mips16Pat< 1561 (select (i32 (setlt CPU16Regs:$a, immSExt16:$b)), 1562 CPU16Regs:$x, CPU16Regs:$y), 1563 (SelTBtneZSlti CPU16Regs:$x, CPU16Regs:$y, 1564 CPU16Regs:$a, immSExt16:$b)>; 1565 1566 1567// 1568// 1569// signed 1570// x = (a <= b)? x : y 1571// 1572// if (b < a) x = y 1573// 1574def : Mips16Pat<(select (i32 (setle CPU16Regs:$a, CPU16Regs:$b)), 1575 CPU16Regs:$x, CPU16Regs:$y), 1576 (SelTBteqZSlt CPU16Regs:$x, CPU16Regs:$y, 1577 CPU16Regs:$b, CPU16Regs:$a)>; 1578 1579// 1580// unnsigned 1581// x = (a <= b)? x : y 1582// 1583// if (b < a) x = y 1584// 1585def : Mips16Pat<(select (i32 (setule CPU16Regs:$a, CPU16Regs:$b)), 1586 CPU16Regs:$x, CPU16Regs:$y), 1587 (SelTBteqZSltu CPU16Regs:$x, CPU16Regs:$y, 1588 CPU16Regs:$b, CPU16Regs:$a)>; 1589 1590// 1591// signed/unsigned 1592// x = (a == b)? x : y 1593// 1594// if (a != b) x = y 1595// 1596def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, CPU16Regs:$b)), 1597 CPU16Regs:$x, CPU16Regs:$y), 1598 (SelTBteqZCmp CPU16Regs:$x, CPU16Regs:$y, 1599 CPU16Regs:$b, CPU16Regs:$a)>; 1600 1601// 1602// signed/unsigned 1603// x = (a == 0)? x : y 1604// 1605// if (a != 0) x = y 1606// 1607def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, 0)), 1608 CPU16Regs:$x, CPU16Regs:$y), 1609 (SelBeqZ CPU16Regs:$x, CPU16Regs:$y, 1610 CPU16Regs:$a)>; 1611 1612 1613// 1614// signed/unsigned 1615// x = (a == k)? x : y 1616// 1617// if (a != k) x = y 1618// 1619def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, immZExt16:$k)), 1620 CPU16Regs:$x, CPU16Regs:$y), 1621 (SelTBteqZCmpi CPU16Regs:$x, CPU16Regs:$y, 1622 CPU16Regs:$a, immZExt16:$k)>; 1623 1624 1625// 1626// signed/unsigned 1627// x = (a != b)? x : y 1628// 1629// if (a == b) x = y 1630// 1631// 1632def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, CPU16Regs:$b)), 1633 CPU16Regs:$x, CPU16Regs:$y), 1634 (SelTBtneZCmp CPU16Regs:$x, CPU16Regs:$y, 1635 CPU16Regs:$b, CPU16Regs:$a)>; 1636 1637// 1638// signed/unsigned 1639// x = (a != 0)? x : y 1640// 1641// if (a == 0) x = y 1642// 1643def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, 0)), 1644 CPU16Regs:$x, CPU16Regs:$y), 1645 (SelBneZ CPU16Regs:$x, CPU16Regs:$y, 1646 CPU16Regs:$a)>; 1647 1648// signed/unsigned 1649// x = (a)? x : y 1650// 1651// if (!a) x = y 1652// 1653def : Mips16Pat<(select CPU16Regs:$a, 1654 CPU16Regs:$x, CPU16Regs:$y), 1655 (SelBneZ CPU16Regs:$x, CPU16Regs:$y, 1656 CPU16Regs:$a)>; 1657 1658 1659// 1660// signed/unsigned 1661// x = (a != k)? x : y 1662// 1663// if (a == k) x = y 1664// 1665def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, immZExt16:$k)), 1666 CPU16Regs:$x, CPU16Regs:$y), 1667 (SelTBtneZCmpi CPU16Regs:$x, CPU16Regs:$y, 1668 CPU16Regs:$a, immZExt16:$k)>; 1669 1670// 1671// When writing C code to test setxx these patterns, 1672// some will be transformed into 1673// other things. So we test using C code but using -O3 and -O0 1674// 1675// seteq 1676// 1677def : Mips16Pat 1678 <(seteq CPU16Regs:$lhs,CPU16Regs:$rhs), 1679 (SltiuCCRxImmX16 (XorRxRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs), 1)>; 1680 1681def : Mips16Pat 1682 <(seteq CPU16Regs:$lhs, 0), 1683 (SltiuCCRxImmX16 CPU16Regs:$lhs, 1)>; 1684 1685 1686// 1687// setge 1688// 1689 1690def: Mips16Pat 1691 <(setge CPU16Regs:$lhs, CPU16Regs:$rhs), 1692 (XorRxRxRy16 (SltCCRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs), 1693 (LiRxImmX16 1))>; 1694 1695// 1696// For constants, llvm transforms this to: 1697// x > (k -1) and then reverses the operands to use setlt. So this pattern 1698// is not used now by the compiler. (Presumably checking that k-1 does not 1699// overflow). The compiler never uses this at a the current time, due to 1700// other optimizations. 1701// 1702//def: Mips16Pat 1703// <(setge CPU16Regs:$lhs, immSExt16:$rhs), 1704// (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, immSExt16:$rhs), 1705// (LiRxImmX16 1))>; 1706 1707// This catches the x >= -32768 case by transforming it to x > -32769 1708// 1709def: Mips16Pat 1710 <(setgt CPU16Regs:$lhs, -32769), 1711 (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, -32768), 1712 (LiRxImmX16 1))>; 1713 1714// 1715// setgt 1716// 1717// 1718 1719def: Mips16Pat 1720 <(setgt CPU16Regs:$lhs, CPU16Regs:$rhs), 1721 (SltCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs)>; 1722 1723// 1724// setle 1725// 1726def: Mips16Pat 1727 <(setle CPU16Regs:$lhs, CPU16Regs:$rhs), 1728 (XorRxRxRy16 (SltCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs), (LiRxImm16 1))>; 1729 1730// 1731// setlt 1732// 1733def: SetCC_R16<setlt, SltCCRxRy16>; 1734 1735def: SetCC_I16<setlt, immSExt16, SltiCCRxImmX16>; 1736 1737// 1738// setne 1739// 1740def : Mips16Pat 1741 <(setne CPU16Regs:$lhs,CPU16Regs:$rhs), 1742 (SltuCCRxRy16 (LiRxImmX16 0), 1743 (XorRxRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs))>; 1744 1745 1746// 1747// setuge 1748// 1749def: Mips16Pat 1750 <(setuge CPU16Regs:$lhs, CPU16Regs:$rhs), 1751 (XorRxRxRy16 (SltuCCRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs), 1752 (LiRxImmX16 1))>; 1753 1754// this pattern will never be used because the compiler will transform 1755// x >= k to x > (k - 1) and then use SLT 1756// 1757//def: Mips16Pat 1758// <(setuge CPU16Regs:$lhs, immZExt16:$rhs), 1759// (XorRxRxRy16 (SltiuCCRxImmX16 CPU16Regs:$lhs, immZExt16:$rhs), 1760// (LiRxImmX16 1))>; 1761 1762// 1763// setugt 1764// 1765def: Mips16Pat 1766 <(setugt CPU16Regs:$lhs, CPU16Regs:$rhs), 1767 (SltuCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs)>; 1768 1769// 1770// setule 1771// 1772def: Mips16Pat 1773 <(setule CPU16Regs:$lhs, CPU16Regs:$rhs), 1774 (XorRxRxRy16 (SltuCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs), (LiRxImmX16 1))>; 1775 1776// 1777// setult 1778// 1779def: SetCC_R16<setult, SltuCCRxRy16>; 1780 1781def: SetCC_I16<setult, immSExt16, SltiuCCRxImmX16>; 1782 1783def: Mips16Pat<(add CPU16Regs:$hi, (MipsLo tglobaladdr:$lo)), 1784 (AddiuRxRxImmX16 CPU16Regs:$hi, tglobaladdr:$lo)>; 1785 1786// hi/lo relocs 1787 1788def : Mips16Pat<(MipsHi tglobaladdr:$in), 1789 (SllX16 (LiRxImmX16 tglobaladdr:$in), 16)>; 1790def : Mips16Pat<(MipsHi tjumptable:$in), 1791 (SllX16 (LiRxImmX16 tjumptable:$in), 16)>; 1792def : Mips16Pat<(MipsHi tglobaltlsaddr:$in), 1793 (SllX16 (LiRxImmX16 tglobaltlsaddr:$in), 16)>; 1794 1795// wrapper_pic 1796class Wrapper16Pat<SDNode node, Instruction ADDiuOp, RegisterClass RC>: 1797 Mips16Pat<(MipsWrapper RC:$gp, node:$in), 1798 (ADDiuOp RC:$gp, node:$in)>; 1799 1800 1801def : Wrapper16Pat<tglobaladdr, AddiuRxRxImmX16, CPU16Regs>; 1802def : Wrapper16Pat<tglobaltlsaddr, AddiuRxRxImmX16, CPU16Regs>; 1803 1804def : Mips16Pat<(i32 (extloadi8 addr16:$src)), 1805 (LbuRxRyOffMemX16 addr16:$src)>; 1806def : Mips16Pat<(i32 (extloadi16 addr16:$src)), 1807 (LhuRxRyOffMemX16 addr16:$src)>; 1808 1809def: Mips16Pat<(trap), (Break16)>; 1810 1811