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