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