@@ -201,7 +201,13 @@ class MipsAsmParser : public MCTargetAsmParser {
201
201
const MCSubtargetInfo *STI);
202
202
203
203
void expandMemInst (MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
204
- const MCSubtargetInfo *STI, bool isLoad, bool isImmOpnd);
204
+ const MCSubtargetInfo *STI, bool IsLoad, bool IsImmOpnd);
205
+
206
+ void expandLoadInst (MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
207
+ const MCSubtargetInfo *STI, bool IsImmOpnd);
208
+
209
+ void expandStoreInst (MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
210
+ const MCSubtargetInfo *STI, bool IsImmOpnd);
205
211
206
212
bool expandLoadStoreMultiple (MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
207
213
const MCSubtargetInfo *STI);
@@ -2526,78 +2532,97 @@ bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2526
2532
}
2527
2533
2528
2534
void MipsAsmParser::expandMemInst (MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2529
- const MCSubtargetInfo *STI, bool isLoad,
2530
- bool isImmOpnd) {
2535
+ const MCSubtargetInfo *STI, bool IsLoad,
2536
+ bool IsImmOpnd) {
2537
+ if (IsLoad) {
2538
+ expandLoadInst (Inst, IDLoc, Out, STI, IsImmOpnd);
2539
+ return ;
2540
+ }
2541
+ expandStoreInst (Inst, IDLoc, Out, STI, IsImmOpnd);
2542
+ }
2543
+
2544
+ void MipsAsmParser::expandLoadInst (MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2545
+ const MCSubtargetInfo *STI, bool IsImmOpnd) {
2531
2546
MipsTargetStreamer &TOut = getTargetStreamer ();
2532
- MCOperand HiOperand, LoOperand;
2533
- unsigned TmpRegNum;
2534
- // 1st operand is either the source or destination register.
2535
- assert (Inst.getOperand (0 ).isReg () && " expected register operand kind" );
2536
- unsigned RegOpNum = Inst.getOperand (0 ).getReg ();
2537
- // 2nd operand is the base register.
2538
- assert (Inst.getOperand (1 ).isReg () && " expected register operand kind" );
2539
- unsigned BaseRegNum = Inst.getOperand (1 ).getReg ();
2540
- // 3rd operand is either an immediate or expression.
2541
- if (isImmOpnd) {
2542
- assert (Inst.getOperand (2 ).isImm () && " expected immediate operand kind" );
2543
- unsigned ImmOffset = Inst.getOperand (2 ).getImm ();
2544
- unsigned LoOffset = ImmOffset & 0x0000ffff ;
2545
- unsigned HiOffset = (ImmOffset & 0xffff0000 ) >> 16 ;
2546
- // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2547
- if (LoOffset & 0x8000 )
2548
- HiOffset++;
2549
- LoOperand = MCOperand::createImm (LoOffset);
2550
- HiOperand = MCOperand::createImm (HiOffset);
2551
- } else {
2552
- const MCExpr *ExprOffset = Inst.getOperand (2 ).getExpr ();
2553
- LoOperand = MCOperand::createExpr (evaluateRelocExpr (ExprOffset, " lo" ));
2554
- HiOperand = MCOperand::createExpr (evaluateRelocExpr (ExprOffset, " hi" ));
2555
- }
2556
- // These are some of the types of expansions we perform here:
2557
- // 1) lw $8, sym => lui $8, %hi(sym)
2558
- // lw $8, %lo(sym)($8)
2559
- // 2) lw $8, offset($9) => lui $8, %hi(offset)
2560
- // add $8, $8, $9
2561
- // lw $8, %lo(offset)($9)
2562
- // 3) lw $8, offset($8) => lui $at, %hi(offset)
2563
- // add $at, $at, $8
2564
- // lw $8, %lo(offset)($at)
2565
- // 4) sw $8, sym => lui $at, %hi(sym)
2566
- // sw $8, %lo(sym)($at)
2567
- // 5) sw $8, offset($8) => lui $at, %hi(offset)
2568
- // add $at, $at, $8
2569
- // sw $8, %lo(offset)($at)
2570
- // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2571
- // ldc1 $f0, %lo(sym)($at)
2572
- //
2573
- // For load instructions we can use the destination register as a temporary
2574
- // if base and dst are different (examples 1 and 2) and if the base register
2575
- // is general purpose otherwise we must use $at (example 6) and error if it's
2576
- // not available. For stores we must use $at (examples 4 and 5) because we
2577
- // must not clobber the source register setting up the offset.
2547
+
2548
+ unsigned DstReg = Inst.getOperand (0 ).getReg ();
2549
+ unsigned BaseReg = Inst.getOperand (1 ).getReg ();
2550
+
2578
2551
const MCInstrDesc &Desc = getInstDesc (Inst.getOpcode ());
2579
- int16_t RegClassOp0 = Desc.OpInfo [0 ].RegClass ;
2580
- unsigned RegClassIDOp0 =
2581
- getContext ().getRegisterInfo ()->getRegClass (RegClassOp0).getID ();
2582
- bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2583
- (RegClassIDOp0 == Mips::GPR64RegClassID);
2584
- if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2585
- TmpRegNum = RegOpNum;
2586
- else {
2552
+ int16_t DstRegClass = Desc.OpInfo [0 ].RegClass ;
2553
+ unsigned DstRegClassID =
2554
+ getContext ().getRegisterInfo ()->getRegClass (DstRegClass).getID ();
2555
+ bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
2556
+ (DstRegClassID == Mips::GPR64RegClassID);
2557
+
2558
+ if (IsImmOpnd) {
2559
+ // Try to use DstReg as the temporary.
2560
+ if (IsGPR && (BaseReg != DstReg)) {
2561
+ TOut.emitLoadWithImmOffset (Inst.getOpcode (), DstReg, BaseReg,
2562
+ Inst.getOperand (2 ).getImm (), DstReg, IDLoc,
2563
+ STI);
2564
+ return ;
2565
+ }
2566
+
2587
2567
// At this point we need AT to perform the expansions and we exit if it is
2588
2568
// not available.
2589
- TmpRegNum = getATReg (IDLoc);
2590
- if (!TmpRegNum )
2569
+ unsigned ATReg = getATReg (IDLoc);
2570
+ if (!ATReg )
2591
2571
return ;
2572
+
2573
+ TOut.emitLoadWithImmOffset (Inst.getOpcode (), DstReg, BaseReg,
2574
+ Inst.getOperand (2 ).getImm (), ATReg, IDLoc, STI);
2575
+ return ;
2576
+ }
2577
+
2578
+ const MCExpr *ExprOffset = Inst.getOperand (2 ).getExpr ();
2579
+ MCOperand LoOperand =
2580
+ MCOperand::createExpr (evaluateRelocExpr (ExprOffset, " lo" ));
2581
+ MCOperand HiOperand =
2582
+ MCOperand::createExpr (evaluateRelocExpr (ExprOffset, " hi" ));
2583
+
2584
+ // Try to use DstReg as the temporary.
2585
+ if (IsGPR && (BaseReg != DstReg)) {
2586
+ TOut.emitLoadWithSymOffset (Inst.getOpcode (), DstReg, BaseReg, HiOperand,
2587
+ LoOperand, DstReg, IDLoc, STI);
2588
+ return ;
2589
+ }
2590
+
2591
+ // At this point we need AT to perform the expansions and we exit if it is
2592
+ // not available.
2593
+ unsigned ATReg = getATReg (IDLoc);
2594
+ if (!ATReg)
2595
+ return ;
2596
+
2597
+ TOut.emitLoadWithSymOffset (Inst.getOpcode (), DstReg, BaseReg, HiOperand,
2598
+ LoOperand, ATReg, IDLoc, STI);
2599
+ }
2600
+
2601
+ void MipsAsmParser::expandStoreInst (MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2602
+ const MCSubtargetInfo *STI,
2603
+ bool IsImmOpnd) {
2604
+ MipsTargetStreamer &TOut = getTargetStreamer ();
2605
+
2606
+ unsigned SrcReg = Inst.getOperand (0 ).getReg ();
2607
+ unsigned BaseReg = Inst.getOperand (1 ).getReg ();
2608
+
2609
+ unsigned ATReg = getATReg (IDLoc);
2610
+ if (!ATReg)
2611
+ return ;
2612
+
2613
+ if (IsImmOpnd) {
2614
+ TOut.emitStoreWithImmOffset (Inst.getOpcode (), SrcReg, BaseReg,
2615
+ Inst.getOperand (2 ).getImm (), ATReg, IDLoc, STI);
2616
+ return ;
2592
2617
}
2593
2618
2594
- TOut. emitRX (Mips::LUi, TmpRegNum, HiOperand, IDLoc, STI );
2595
- // Add temp register to base.
2596
- if (BaseRegNum != Mips::ZERO)
2597
- TOut. emitRRR (Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, STI);
2598
- // And finally, create original instruction with low part
2599
- // of offset and new base.
2600
- TOut. emitRRX (Inst. getOpcode (), RegOpNum, TmpRegNum, LoOperand, IDLoc, STI);
2619
+ const MCExpr *ExprOffset = Inst. getOperand ( 2 ). getExpr ( );
2620
+ MCOperand LoOperand =
2621
+ MCOperand::createExpr ( evaluateRelocExpr (ExprOffset, " lo " ));
2622
+ MCOperand HiOperand =
2623
+ MCOperand::createExpr ( evaluateRelocExpr (ExprOffset, " hi " ));
2624
+ TOut. emitStoreWithSymOffset (Inst. getOpcode (), SrcReg, BaseReg, HiOperand,
2625
+ LoOperand, ATReg , IDLoc, STI);
2601
2626
}
2602
2627
2603
2628
bool MipsAsmParser::expandLoadStoreMultiple (MCInst &Inst, SMLoc IDLoc,
0 commit comments