@@ -32,6 +32,8 @@ namespace {
32
32
enum OperandTransfer {
33
33
OT_NA, // /< Not applicable
34
34
OT_OperandsAll, // /< Transfer all operands
35
+ OT_Operands02, // /< Transfer operands 0 and 2
36
+ OT_Operand2, // /< Transfer just operand 2
35
37
};
36
38
37
39
// / Reduction type
@@ -143,27 +145,44 @@ class MicroMipsSizeReduce : public MachineFunctionPass {
143
145
// returns true on success.
144
146
static bool ReduceSXtoSX16 (MachineInstr *MI, const ReduceEntry &Entry);
145
147
146
- // Attempts to reduce arithmetic instructions, returns true on success
148
+ // Attempts to reduce arithmetic instructions, returns true on success.
147
149
static bool ReduceArithmeticInstructions (MachineInstr *MI,
148
150
const ReduceEntry &Entry);
149
151
150
- // Changes opcode of an instruction
152
+ // Attempts to reduce ADDIU into ADDIUSP instruction,
153
+ // returns true on success.
154
+ static bool ReduceADDIUToADDIUSP (MachineInstr *MI, const ReduceEntry &Entry);
155
+
156
+ // Attempts to reduce ADDIU into ADDIUR1SP instruction,
157
+ // returns true on success.
158
+ static bool ReduceADDIUToADDIUR1SP (MachineInstr *MI,
159
+ const ReduceEntry &Entry);
160
+
161
+ // Changes opcode of an instruction.
151
162
static bool ReplaceInstruction (MachineInstr *MI, const ReduceEntry &Entry);
152
163
153
- // Table with transformation rules for each instruction
164
+ // Table with transformation rules for each instruction.
154
165
static llvm::SmallVector<ReduceEntry, 16 > ReduceTable;
155
166
};
156
167
157
168
char MicroMipsSizeReduce::ID = 0 ;
158
169
const MipsInstrInfo *MicroMipsSizeReduce::MipsII;
159
170
160
171
// This table must be sorted by WideOpc as a main criterion and
161
- // ReduceType as a sub-criterion (when wide opcodes are the same)
172
+ // ReduceType as a sub-criterion (when wide opcodes are the same).
162
173
llvm::SmallVector<ReduceEntry, 16 > MicroMipsSizeReduce::ReduceTable = {
163
174
164
175
// ReduceType, OpCodes, ReduceFunction,
165
176
// OpInfo(TransferOperands),
166
177
// ImmField(Shift, LBound, HBound, ImmFieldPosition)
178
+ {RT_OneInstr, OpCodes (Mips::ADDiu, Mips::ADDIUR1SP_MM),
179
+ ReduceADDIUToADDIUR1SP, OpInfo (OT_Operands02), ImmField (2 , 0 , 64 , 2 )},
180
+ {RT_OneInstr, OpCodes (Mips::ADDiu, Mips::ADDIUSP_MM), ReduceADDIUToADDIUSP,
181
+ OpInfo (OT_Operand2), ImmField (0 , 0 , 0 , 2 )},
182
+ {RT_OneInstr, OpCodes (Mips::ADDiu_MM, Mips::ADDIUR1SP_MM),
183
+ ReduceADDIUToADDIUR1SP, OpInfo (OT_Operands02), ImmField (2 , 0 , 64 , 2 )},
184
+ {RT_OneInstr, OpCodes (Mips::ADDiu_MM, Mips::ADDIUSP_MM),
185
+ ReduceADDIUToADDIUSP, OpInfo (OT_Operand2), ImmField (0 , 0 , 0 , 2 )},
167
186
{RT_OneInstr, OpCodes (Mips::ADDu, Mips::ADDU16_MM),
168
187
ReduceArithmeticInstructions, OpInfo (OT_OperandsAll),
169
188
ImmField (0 , 0 , 0 , -1 )},
@@ -174,6 +193,8 @@ llvm::SmallVector<ReduceEntry, 16> MicroMipsSizeReduce::ReduceTable = {
174
193
OpInfo (OT_OperandsAll), ImmField (0 , -1 , 15 , 2 )},
175
194
{RT_OneInstr, OpCodes (Mips::LBu_MM, Mips::LBU16_MM), ReduceLXUtoLXU16,
176
195
OpInfo (OT_OperandsAll), ImmField (0 , -1 , 15 , 2 )},
196
+ {RT_OneInstr, OpCodes (Mips::LEA_ADDiu, Mips::ADDIUR1SP_MM),
197
+ ReduceADDIUToADDIUR1SP, OpInfo (OT_Operands02), ImmField (2 , 0 , 64 , 2 )},
177
198
{RT_OneInstr, OpCodes (Mips::LHu, Mips::LHU16_MM), ReduceLXUtoLXU16,
178
199
OpInfo (OT_OperandsAll), ImmField (1 , 0 , 16 , 2 )},
179
200
{RT_OneInstr, OpCodes (Mips::LHu_MM, Mips::LHU16_MM), ReduceLXUtoLXU16,
@@ -201,9 +222,9 @@ llvm::SmallVector<ReduceEntry, 16> MicroMipsSizeReduce::ReduceTable = {
201
222
{RT_OneInstr, OpCodes (Mips::SW_MM, Mips::SWSP_MM), ReduceXWtoXWSP,
202
223
OpInfo (OT_OperandsAll), ImmField (2 , 0 , 32 , 2 )},
203
224
};
204
- }
225
+ } // namespace
205
226
206
- // Returns true if the machine operand MO is register SP
227
+ // Returns true if the machine operand MO is register SP.
207
228
static bool IsSP (const MachineOperand &MO) {
208
229
if (MO.isReg () && ((MO.getReg () == Mips::SP)))
209
230
return true ;
@@ -225,7 +246,7 @@ static bool isMMSourceRegister(const MachineOperand &MO) {
225
246
}
226
247
227
248
// Returns true if the operand Op is an immediate value
228
- // and writes the immediate value into variable Imm
249
+ // and writes the immediate value into variable Imm.
229
250
static bool GetImm (MachineInstr *MI, unsigned Op, int64_t &Imm) {
230
251
231
252
if (!MI->getOperand (Op).isImm ())
@@ -234,17 +255,27 @@ static bool GetImm(MachineInstr *MI, unsigned Op, int64_t &Imm) {
234
255
return true ;
235
256
}
236
257
258
+ // Returns true if the value is a valid immediate for ADDIUSP.
259
+ static bool AddiuspImmValue (int64_t Value) {
260
+ int64_t Value2 = Value >> 2 ;
261
+ if (((Value & (int64_t )maskTrailingZeros<u_int64_t >(2 )) == Value) &&
262
+ ((Value2 >= 2 && Value2 <= 257 ) || (Value2 >= -258 && Value2 <= -3 )))
263
+ return true ;
264
+ return false ;
265
+ }
266
+
237
267
// Returns true if the variable Value has the number of least-significant zero
238
- // bits equal to Shift and if the shifted value is between the bounds
268
+ // bits equal to Shift and if the shifted value is between the bounds.
239
269
static bool InRange (int64_t Value, unsigned short Shift, int LBound,
240
270
int HBound) {
241
271
int64_t Value2 = Value >> Shift;
242
- if ((Value2 << Shift) == Value && (Value2 >= LBound) && (Value2 < HBound))
272
+ if (((Value & (int64_t )maskTrailingZeros<u_int64_t >(Shift)) == Value) &&
273
+ (Value2 >= LBound) && (Value2 < HBound))
243
274
return true ;
244
275
return false ;
245
276
}
246
277
247
- // Returns true if immediate operand is in range
278
+ // Returns true if immediate operand is in range.
248
279
static bool ImmInRange (MachineInstr *MI, const ReduceEntry &Entry) {
249
280
250
281
int64_t offset;
@@ -310,6 +341,34 @@ bool MicroMipsSizeReduce::ReduceArithmeticInstructions(
310
341
return ReplaceInstruction (MI, Entry);
311
342
}
312
343
344
+ bool MicroMipsSizeReduce::ReduceADDIUToADDIUR1SP (MachineInstr *MI,
345
+ const ReduceEntry &Entry) {
346
+
347
+ if (!ImmInRange (MI, Entry))
348
+ return false ;
349
+
350
+ if (!isMMThreeBitGPRegister (MI->getOperand (0 )) || !IsSP (MI->getOperand (1 )))
351
+ return false ;
352
+
353
+ return ReplaceInstruction (MI, Entry);
354
+ }
355
+
356
+ bool MicroMipsSizeReduce::ReduceADDIUToADDIUSP (MachineInstr *MI,
357
+ const ReduceEntry &Entry) {
358
+
359
+ int64_t ImmValue;
360
+ if (!GetImm (MI, Entry.ImmField (), ImmValue))
361
+ return false ;
362
+
363
+ if (!AddiuspImmValue (ImmValue))
364
+ return false ;
365
+
366
+ if (!IsSP (MI->getOperand (0 )) || !IsSP (MI->getOperand (1 )))
367
+ return false ;
368
+
369
+ return ReplaceInstruction (MI, Entry);
370
+ }
371
+
313
372
bool MicroMipsSizeReduce::ReduceLXUtoLXU16 (MachineInstr *MI,
314
373
const ReduceEntry &Entry) {
315
374
@@ -361,10 +420,37 @@ bool MicroMipsSizeReduce::ReduceMBB(MachineBasicBlock &MBB) {
361
420
bool MicroMipsSizeReduce::ReplaceInstruction (MachineInstr *MI,
362
421
const ReduceEntry &Entry) {
363
422
364
- MI->setDesc (MipsII->get (Entry.NarrowOpc ()));
365
- DEBUG (dbgs () << " Converted into 16-bit: " << *MI);
423
+ enum OperandTransfer OpTransfer = Entry.TransferOperands ();
424
+
425
+ DEBUG (dbgs () << " Converting 32-bit: " << *MI);
366
426
++NumReduced;
367
- return true ;
427
+
428
+ if (OpTransfer == OT_OperandsAll) {
429
+ MI->setDesc (MipsII->get (Entry.NarrowOpc ()));
430
+ DEBUG (dbgs () << " to 16-bit: " << *MI);
431
+ return true ;
432
+ } else {
433
+ MachineBasicBlock &MBB = *MI->getParent ();
434
+ const MCInstrDesc &NewMCID = MipsII->get (Entry.NarrowOpc ());
435
+ DebugLoc dl = MI->getDebugLoc ();
436
+ MachineInstrBuilder MIB = BuildMI (MBB, MI, dl, NewMCID);
437
+
438
+ if (OpTransfer == OT_Operand2)
439
+ MIB.add (MI->getOperand (2 ));
440
+ else if (OpTransfer == OT_Operands02) {
441
+ MIB.add (MI->getOperand (0 ));
442
+ MIB.add (MI->getOperand (2 ));
443
+ } else
444
+ llvm_unreachable (" Unknown operand transfer!" );
445
+
446
+ // Transfer MI flags.
447
+ MIB.setMIFlags (MI->getFlags ());
448
+
449
+ DEBUG (dbgs () << " to 16-bit: " << *MIB);
450
+ MBB.erase_instr (MI);
451
+ return true ;
452
+ }
453
+ return false ;
368
454
}
369
455
370
456
bool MicroMipsSizeReduce::runOnMachineFunction (MachineFunction &MF) {
@@ -373,7 +459,8 @@ bool MicroMipsSizeReduce::runOnMachineFunction(MachineFunction &MF) {
373
459
374
460
// TODO: Add support for other subtargets:
375
461
// microMIPS32r6 and microMIPS64r6
376
- if (!Subtarget->inMicroMipsMode () || !Subtarget->hasMips32r2 ())
462
+ if (!Subtarget->inMicroMipsMode () || !Subtarget->hasMips32r2 () ||
463
+ Subtarget->hasMips32r6 ())
377
464
return false ;
378
465
379
466
MipsII = static_cast <const MipsInstrInfo *>(Subtarget->getInstrInfo ());
0 commit comments