@@ -101,6 +101,9 @@ M68kTargetLowering::M68kTargetLowering(const M68kTargetMachine &TM,
101
101
setOperationAction (OP, MVT::i32, Expand);
102
102
}
103
103
104
+ for (auto OP : {ISD::SHL_PARTS, ISD::SRA_PARTS, ISD::SRL_PARTS})
105
+ setOperationAction (OP, MVT::i32, Custom);
106
+
104
107
// Add/Sub overflow ops with MVT::Glues are lowered to CCR dependences.
105
108
for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
106
109
setOperationAction (ISD::ADDC, VT, Custom);
@@ -1354,6 +1357,12 @@ SDValue M68kTargetLowering::LowerOperation(SDValue Op,
1354
1357
return LowerVASTART (Op, DAG);
1355
1358
case ISD::DYNAMIC_STACKALLOC:
1356
1359
return LowerDYNAMIC_STACKALLOC (Op, DAG);
1360
+ case ISD::SHL_PARTS:
1361
+ return LowerShiftLeftParts (Op, DAG);
1362
+ case ISD::SRA_PARTS:
1363
+ return LowerShiftRightParts (Op, DAG, true );
1364
+ case ISD::SRL_PARTS:
1365
+ return LowerShiftRightParts (Op, DAG, false );
1357
1366
}
1358
1367
}
1359
1368
@@ -3239,6 +3248,102 @@ SDValue M68kTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
3239
3248
return DAG.getMergeValues (Ops, DL);
3240
3249
}
3241
3250
3251
+ SDValue M68kTargetLowering::LowerShiftLeftParts (SDValue Op,
3252
+ SelectionDAG &DAG) const {
3253
+ SDLoc DL (Op);
3254
+ SDValue Lo = Op.getOperand (0 );
3255
+ SDValue Hi = Op.getOperand (1 );
3256
+ SDValue Shamt = Op.getOperand (2 );
3257
+ EVT VT = Lo.getValueType ();
3258
+
3259
+ // if Shamt - register size < 0: // Shamt < register size
3260
+ // Lo = Lo << Shamt
3261
+ // Hi = (Hi << Shamt) | ((Lo >>u 1) >>u (register size - 1 ^ Shamt))
3262
+ // else:
3263
+ // Lo = 0
3264
+ // Hi = Lo << (Shamt - register size)
3265
+
3266
+ SDValue Zero = DAG.getConstant (0 , DL, VT);
3267
+ SDValue One = DAG.getConstant (1 , DL, VT);
3268
+ SDValue MinusRegisterSize = DAG.getConstant (-32 , DL, VT);
3269
+ SDValue RegisterSizeMinus1 = DAG.getConstant (32 - 1 , DL, VT);
3270
+ SDValue ShamtMinusRegisterSize =
3271
+ DAG.getNode (ISD::ADD, DL, VT, Shamt, MinusRegisterSize);
3272
+ SDValue RegisterSizeMinus1Shamt =
3273
+ DAG.getNode (ISD::XOR, DL, VT, RegisterSizeMinus1, Shamt);
3274
+
3275
+ SDValue LoTrue = DAG.getNode (ISD::SHL, DL, VT, Lo, Shamt);
3276
+ SDValue ShiftRight1Lo = DAG.getNode (ISD::SRL, DL, VT, Lo, One);
3277
+ SDValue ShiftRightLo =
3278
+ DAG.getNode (ISD::SRL, DL, VT, ShiftRight1Lo, RegisterSizeMinus1Shamt);
3279
+ SDValue ShiftLeftHi = DAG.getNode (ISD::SHL, DL, VT, Hi, Shamt);
3280
+ SDValue HiTrue = DAG.getNode (ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo);
3281
+ SDValue HiFalse = DAG.getNode (ISD::SHL, DL, VT, Lo, ShamtMinusRegisterSize);
3282
+
3283
+ SDValue CC =
3284
+ DAG.getSetCC (DL, MVT::i8, ShamtMinusRegisterSize, Zero, ISD::SETLT);
3285
+
3286
+ Lo = DAG.getNode (ISD::SELECT, DL, VT, CC, LoTrue, Zero);
3287
+ Hi = DAG.getNode (ISD::SELECT, DL, VT, CC, HiTrue, HiFalse);
3288
+
3289
+ return DAG.getMergeValues ({Lo, Hi}, DL);
3290
+ }
3291
+
3292
+ SDValue M68kTargetLowering::LowerShiftRightParts (SDValue Op, SelectionDAG &DAG,
3293
+ bool IsSRA) const {
3294
+ SDLoc DL (Op);
3295
+ SDValue Lo = Op.getOperand (0 );
3296
+ SDValue Hi = Op.getOperand (1 );
3297
+ SDValue Shamt = Op.getOperand (2 );
3298
+ EVT VT = Lo.getValueType ();
3299
+
3300
+ // SRA expansion:
3301
+ // if Shamt - register size < 0: // Shamt < register size
3302
+ // Lo = (Lo >>u Shamt) | ((Hi << 1) << (register size - 1 ^ Shamt))
3303
+ // Hi = Hi >>s Shamt
3304
+ // else:
3305
+ // Lo = Hi >>s (Shamt - register size);
3306
+ // Hi = Hi >>s (register size - 1)
3307
+ //
3308
+ // SRL expansion:
3309
+ // if Shamt - register size < 0: // Shamt < register size
3310
+ // Lo = (Lo >>u Shamt) | ((Hi << 1) << (register size - 1 ^ Shamt))
3311
+ // Hi = Hi >>u Shamt
3312
+ // else:
3313
+ // Lo = Hi >>u (Shamt - register size);
3314
+ // Hi = 0;
3315
+
3316
+ unsigned ShiftRightOp = IsSRA ? ISD::SRA : ISD::SRL;
3317
+
3318
+ SDValue Zero = DAG.getConstant (0 , DL, VT);
3319
+ SDValue One = DAG.getConstant (1 , DL, VT);
3320
+ SDValue MinusRegisterSize = DAG.getConstant (-32 , DL, VT);
3321
+ SDValue RegisterSizeMinus1 = DAG.getConstant (32 - 1 , DL, VT);
3322
+ SDValue ShamtMinusRegisterSize =
3323
+ DAG.getNode (ISD::ADD, DL, VT, Shamt, MinusRegisterSize);
3324
+ SDValue RegisterSizeMinus1Shamt =
3325
+ DAG.getNode (ISD::XOR, DL, VT, RegisterSizeMinus1, Shamt);
3326
+
3327
+ SDValue ShiftRightLo = DAG.getNode (ISD::SRL, DL, VT, Lo, Shamt);
3328
+ SDValue ShiftLeftHi1 = DAG.getNode (ISD::SHL, DL, VT, Hi, One);
3329
+ SDValue ShiftLeftHi =
3330
+ DAG.getNode (ISD::SHL, DL, VT, ShiftLeftHi1, RegisterSizeMinus1Shamt);
3331
+ SDValue LoTrue = DAG.getNode (ISD::OR, DL, VT, ShiftRightLo, ShiftLeftHi);
3332
+ SDValue HiTrue = DAG.getNode (ShiftRightOp, DL, VT, Hi, Shamt);
3333
+ SDValue LoFalse =
3334
+ DAG.getNode (ShiftRightOp, DL, VT, Hi, ShamtMinusRegisterSize);
3335
+ SDValue HiFalse =
3336
+ IsSRA ? DAG.getNode (ISD::SRA, DL, VT, Hi, RegisterSizeMinus1) : Zero;
3337
+
3338
+ SDValue CC =
3339
+ DAG.getSetCC (DL, MVT::i8, ShamtMinusRegisterSize, Zero, ISD::SETLT);
3340
+
3341
+ Lo = DAG.getNode (ISD::SELECT, DL, VT, CC, LoTrue, LoFalse);
3342
+ Hi = DAG.getNode (ISD::SELECT, DL, VT, CC, HiTrue, HiFalse);
3343
+
3344
+ return DAG.getMergeValues ({Lo, Hi}, DL);
3345
+ }
3346
+
3242
3347
// ===----------------------------------------------------------------------===//
3243
3348
// DAG Combine
3244
3349
// ===----------------------------------------------------------------------===//
0 commit comments