Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -751,8 +751,10 @@ let DecoderMethod = "DecodeMemMMImm16" in { def LB_MM : Load<"lb", GPR32Opnd>, MMRel, LW_FM_MM<0x7>; def LBu_MM : Load<"lbu", GPR32Opnd>, MMRel, LW_FM_MM<0x5>; - def LH_MM : Load<"lh", GPR32Opnd>, MMRel, LW_FM_MM<0xf>; - def LHu_MM : Load<"lhu", GPR32Opnd>, MMRel, LW_FM_MM<0xd>; + def LH_MM : LoadMemory<"lh", GPR32Opnd, mem_simm16gpr>, MMRel, + LW_FM_MM<0xf>; + def LHu_MM : LoadMemory<"lhu", GPR32Opnd, mem_simm16gpr>, MMRel, + LW_FM_MM<0xd>; def LW_MM : Load<"lw", GPR32Opnd>, MMRel, LW_FM_MM<0x3f>; def SB_MM : Store<"sb", GPR32Opnd>, MMRel, LW_FM_MM<0x6>; def SH_MM : Store<"sh", GPR32Opnd>, MMRel, LW_FM_MM<0xe>; @@ -762,8 +764,10 @@ let DecoderMethod = "DecodeMemMMImm9" in { def LBE_MM : Load<"lbe", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x4>; def LBuE_MM : Load<"lbue", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x0>; - def LHE_MM : Load<"lhe", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x5>; - def LHuE_MM : Load<"lhue", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x1>; + def LHE_MM : LoadMemory<"lhe", GPR32Opnd, mem_simm9gpr>, + POOL32C_LHUE_FM_MM<0x18, 0x6, 0x5>; + def LHuE_MM : LoadMemory<"lhue", GPR32Opnd, mem_simm9gpr>, + POOL32C_LHUE_FM_MM<0x18, 0x6, 0x1>; def LWE_MM : Load<"lwe", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x7>; def SBE_MM : Store<"sbe", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0xa, 0x4>; def SHE_MM : Store<"she", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0xa, 0x5>; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -547,6 +547,14 @@ let PredicateMethod = "isMemWithSimmOffset<16>"; } +def MipsMemSimm16GPRAsmOperand : AsmOperandClass { + let Name = "MemOffsetSimm16GPR"; + let SuperClasses = [MipsMemAsmOperand]; + let RenderMethod = "addMemOperands"; + let ParserMethod = "parseMemOperand"; + let PredicateMethod = "isMemWithSimmOffsetGPR<16>"; +} + def MipsInvertedImmoperand : AsmOperandClass { let Name = "InvNum"; let RenderMethod = "addImmOperands"; @@ -602,6 +610,12 @@ let ParserMatchClass = MipsMemSimm16AsmOperand; } +def mem_simm16gpr : mem_generic { + let MIOperandInfo = (ops ptr_rc, simm16); + let EncoderMethod = "getMemEncoding"; + let ParserMatchClass = MipsMemSimm16GPRAsmOperand; +} + def mem_ea : Operand { let PrintMethod = "printMemOperandEA"; let MIOperandInfo = (ops ptr_rc, simm16); @@ -769,15 +783,21 @@ } // Memory Load/Store -class Load : - InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"), +class LoadMemory : + InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> { let DecoderMethod = "DecodeMem"; let canFoldAsLoad = 1; let mayLoad = 1; } +class Load : + LoadMemory; + class StoreMemory : @@ -1323,9 +1343,12 @@ def LB : Load<"lb", GPR32Opnd, sextloadi8, II_LB>, MMRel, LW_FM<0x20>; def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel, LW_FM<0x24>; -def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel, - LW_FM<0x21>; -def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>; +let AdditionalPredicates = [NotInMicroMips] in { + def LH : LoadMemory<"lh", GPR32Opnd, mem_simm16gpr, sextloadi16, II_LH, + addrDefault>, MMRel, LW_FM<0x21>; + def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simm16gpr, zextloadi16, II_LHU>, + MMRel, LW_FM<0x25>; +} let AdditionalPredicates = [NotInMicroMips] in { def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel, LW_FM<0x23>; Index: test/MC/Disassembler/Mips/micromips32r6/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips32r6/valid.txt +++ test/MC/Disassembler/Mips/micromips32r6/valid.txt @@ -237,3 +237,7 @@ 0xea 0x11 # CHECK: sw16 $4, 4($17) 0xe8 0x11 # CHECK: sw16 $zero, 4($17) 0x45 0x2a # CHECK: swm16 $16, $17, $ra, 8($sp) +0x3c 0x44 0x00 0x08 # CHECK: lh $2, 8($4) +0x60 0x82 0x6a 0x08 # CHECK: lhe $4, 8($2) +0x34 0x82 0x00 0x08 # CHECK: lhu $4, 8($2) +0x60 0x82 0x62 0x08 # CHECK: lhue $4, 8($2) Index: test/MC/Disassembler/Mips/micromips64r6/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips64r6/valid.txt +++ test/MC/Disassembler/Mips/micromips64r6/valid.txt @@ -150,3 +150,7 @@ 0xea 0x11 # CHECK: sw16 $4, 4($17) 0xe8 0x11 # CHECK: sw16 $zero, 4($17) 0x45 0x2a # CHECK: swm16 $16, $17, $ra, 8($sp) +0x3c 0x44 0x00 0x08 # CHECK: lh $2, 8($4) +0x60 0x82 0x6a 0x08 # CHECK: lhe $4, 8($2) +0x34 0x82 0x00 0x08 # CHECK: lhu $4, 8($2) +0x60 0x82 0x62 0x08 # CHECK: lhue $4, 8($2) Index: test/MC/Mips/micromips-invalid.s =================================================================== --- test/MC/Mips/micromips-invalid.s +++ test/MC/Mips/micromips-invalid.s @@ -88,3 +88,15 @@ jraddiusp 33 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction jraddiusp 125 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction jraddiusp 132 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $33, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhe $34, 8($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $35, 8($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhue $36, 8($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $2, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhe $4, 8($33) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $4, 8($35) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhue $4, 8($37) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $2, 65536($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhe $4, 512($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $4, 65536($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhue $4, 512($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/micromips32r6/invalid.s =================================================================== --- test/MC/Mips/micromips32r6/invalid.s +++ test/MC/Mips/micromips32r6/invalid.s @@ -101,3 +101,15 @@ swm16 $16-$20, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction swm16 $16, $17, $ra, 8($fp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction swm16 $16, $17, $ra, 64($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $33, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhe $34, 8($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $35, 8($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhue $36, 8($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $2, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhe $4, 8($33) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $4, 8($35) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhue $4, 8($37) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $2, 65536($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhe $4, 512($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $4, 65536($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhue $4, 512($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/micromips32r6/valid.s =================================================================== --- test/MC/Mips/micromips32r6/valid.s +++ test/MC/Mips/micromips32r6/valid.s @@ -230,3 +230,7 @@ lbu $4, 8($5) # CHECK: lbu $4, 8($5) # encoding: [0x14,0x85,0x00,0x08] lbe $4, 8($5) # CHECK: lbe $4, 8($5) # encoding: [0x60,0x85,0x68,0x08] lbue $4, 8($5) # CHECK: lbue $4, 8($5) # encoding: [0x60,0x85,0x60,0x08] + lh $2, 8($4) # CHECK: lh $2, 8($4) # encoding: [0x3c,0x44,0x00,0x08] + lhe $4, 8($2) # CHECK: lhe $4, 8($2) # encoding: [0x60,0x82,0x6a,0x08] + lhu $4, 8($2) # CHECK: lhu $4, 8($2) # encoding: [0x34,0x82,0x00,0x08] + lhue $4, 8($2) # CHECK: lhue $4, 8($2) # encoding: [0x60,0x82,0x62,0x08] Index: test/MC/Mips/micromips64r6/invalid.s =================================================================== --- test/MC/Mips/micromips64r6/invalid.s +++ test/MC/Mips/micromips64r6/invalid.s @@ -109,3 +109,15 @@ swm16 $16-$20, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction swm16 $16, $17, $ra, 8($fp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction swm16 $16, $17, $ra, 64($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $33, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhe $34, 8($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $35, 8($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhue $36, 8($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $2, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhe $4, 8($33) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $4, 8($35) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhue $4, 8($37) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $2, 65536($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhe $4, 512($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $4, 65536($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhue $4, 512($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/micromips64r6/valid.s =================================================================== --- test/MC/Mips/micromips64r6/valid.s +++ test/MC/Mips/micromips64r6/valid.s @@ -130,5 +130,9 @@ sw16 $0, 4($17) # CHECK: sw16 $zero, 4($17) # encoding: [0xe8,0x11] swm $16, $17, $ra, 8($sp) # CHECK: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x2a] swm16 $16, $17, $ra, 8($sp) # CHECK: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x2a] + lh $2, 8($4) # CHECK: lh $2, 8($4) # encoding: [0x3c,0x44,0x00,0x08] + lhe $4, 8($2) # CHECK: lhe $4, 8($2) # encoding: [0x60,0x82,0x6a,0x08] + lhu $4, 8($2) # CHECK: lhu $4, 8($2) # encoding: [0x34,0x82,0x00,0x08] + lhue $4, 8($2) # CHECK: lhue $4, 8($2) # encoding: [0x60,0x82,0x62,0x08] 1: Index: test/MC/Mips/mips32r6/invalid.s =================================================================== --- test/MC/Mips/mips32r6/invalid.s +++ test/MC/Mips/mips32r6/invalid.s @@ -19,6 +19,12 @@ break 1024, 5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction break 7, 1024 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction break 1024, 1024 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $33, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $35, 8($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $2, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $4, 8($35) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $2, 65536($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $4, 65536($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction // FIXME: Following tests are temporarely disabled, until "PredicateControl not in hierarchy" problem is resolved bltl $7, $8, local_label # -CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled bltul $7, $8, local_label # -CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled Index: test/MC/Mips/mips64r6/invalid.s =================================================================== --- test/MC/Mips/mips64r6/invalid.s +++ test/MC/Mips/mips64r6/invalid.s @@ -17,6 +17,12 @@ break 1024, 5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction break 7, 1024 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction break 1024, 1024 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $33, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $35, 8($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $2, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $4, 8($35) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lh $2, 65536($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + lhu $4, 65536($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction // FIXME: Following tests are temporarely disabled, until "PredicateControl not in hierarchy" problem is resolved bltl $7, $8, local_label # -CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled bltul $7, $8, local_label # -CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled