Changeset View
Standalone View
llvm/lib/Target/M68k/M68kISelLowering.cpp
//===-- M68kISelLowering.cpp - M68k DAG Lowering Impl ------*- C++ -*--===// | //===-- M68kISelLowering.cpp - M68k DAG Lowering Impl ------*- C++ -*--===// | ||||||||||||
Lint: Lint: clang-format not found in user’s local PATH; not linting file. | |||||||||||||
// | // | ||||||||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||||||||||
// See https://llvm.org/LICENSE.txt for license information. | // See https://llvm.org/LICENSE.txt for license information. | ||||||||||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||||||||
// | // | ||||||||||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||||||||
/// | /// | ||||||||||||
▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | M68kTargetLowering::M68kTargetLowering(const M68kTargetMachine &TM, | ||||||||||||
// FIXME It would be better to use a custom lowering | // FIXME It would be better to use a custom lowering | ||||||||||||
for (auto OP : {ISD::SMULO, ISD::UMULO}) { | for (auto OP : {ISD::SMULO, ISD::UMULO}) { | ||||||||||||
setOperationAction(OP, MVT::i8, Expand); | setOperationAction(OP, MVT::i8, Expand); | ||||||||||||
setOperationAction(OP, MVT::i16, Expand); | setOperationAction(OP, MVT::i16, Expand); | ||||||||||||
setOperationAction(OP, MVT::i32, Expand); | setOperationAction(OP, MVT::i32, Expand); | ||||||||||||
} | } | ||||||||||||
for (auto OP : {ISD::SHL_PARTS, ISD::SRA_PARTS, ISD::SRL_PARTS}) | |||||||||||||
Not Done ReplyInline ActionsPlease remove curly brace if there is only one statement in for-loop. myhsu: Please remove curly brace if there is only one statement in for-loop. | |||||||||||||
setOperationAction(OP, MVT::i32, Custom); | |||||||||||||
// Add/Sub overflow ops with MVT::Glues are lowered to CCR dependences. | // Add/Sub overflow ops with MVT::Glues are lowered to CCR dependences. | ||||||||||||
for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) { | for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) { | ||||||||||||
setOperationAction(ISD::ADDC, VT, Custom); | setOperationAction(ISD::ADDC, VT, Custom); | ||||||||||||
setOperationAction(ISD::ADDE, VT, Custom); | setOperationAction(ISD::ADDE, VT, Custom); | ||||||||||||
setOperationAction(ISD::SUBC, VT, Custom); | setOperationAction(ISD::SUBC, VT, Custom); | ||||||||||||
setOperationAction(ISD::SUBE, VT, Custom); | setOperationAction(ISD::SUBE, VT, Custom); | ||||||||||||
} | } | ||||||||||||
▲ Show 20 Lines • Show All 262 Lines • ▼ Show 20 Lines | |||||||||||||
} | } | ||||||||||||
SDValue | SDValue | ||||||||||||
M68kTargetLowering::LowerMemArgument(SDValue Chain, CallingConv::ID CallConv, | M68kTargetLowering::LowerMemArgument(SDValue Chain, CallingConv::ID CallConv, | ||||||||||||
const SmallVectorImpl<ISD::InputArg> &Ins, | const SmallVectorImpl<ISD::InputArg> &Ins, | ||||||||||||
const SDLoc &DL, SelectionDAG &DAG, | const SDLoc &DL, SelectionDAG &DAG, | ||||||||||||
const CCValAssign &VA, | const CCValAssign &VA, | ||||||||||||
MachineFrameInfo &MFI, | MachineFrameInfo &MFI, | ||||||||||||
unsigned ArgIdx) const { | unsigned ArgIdx) const { | ||||||||||||
Not Done ReplyInline ActionsI feel like this is modified by clang-format. Can you format only the part you changed using clang/tools/clang-format/clang-format-diff.py myhsu: I feel like this is modified by clang-format. Can you format //only// the part you changed… | |||||||||||||
// Create the nodes corresponding to a load from this parameter slot. | // Create the nodes corresponding to a load from this parameter slot. | ||||||||||||
ISD::ArgFlagsTy Flags = Ins[ArgIdx].Flags; | ISD::ArgFlagsTy Flags = Ins[ArgIdx].Flags; | ||||||||||||
EVT ValVT; | EVT ValVT; | ||||||||||||
// If value is passed by pointer we have address passed instead of the value | // If value is passed by pointer we have address passed instead of the value | ||||||||||||
// itself. | // itself. | ||||||||||||
if (VA.getLocInfo() == CCValAssign::Indirect) | if (VA.getLocInfo() == CCValAssign::Indirect) | ||||||||||||
ValVT = VA.getLocVT(); | ValVT = VA.getLocVT(); | ||||||||||||
▲ Show 20 Lines • Show All 919 Lines • ▼ Show 20 Lines | bool M68kTargetLowering::IsEligibleForTailCallOptimization( | ||||||||||||
return true; | return true; | ||||||||||||
} | } | ||||||||||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||||||||
// Custom Lower | // Custom Lower | ||||||||||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||||||||
SDValue M68kTargetLowering::LowerOperation(SDValue Op, | SDValue M68kTargetLowering::LowerOperation(SDValue Op, | ||||||||||||
Not Done ReplyInline ActionsKeep order in this file consistent with the header jrtc27: Keep order in this file consistent with the header | |||||||||||||
SelectionDAG &DAG) const { | SelectionDAG &DAG) const { | ||||||||||||
switch (Op.getOpcode()) { | switch (Op.getOpcode()) { | ||||||||||||
default: | default: | ||||||||||||
llvm_unreachable("Should not custom lower this!"); | llvm_unreachable("Should not custom lower this!"); | ||||||||||||
case ISD::SADDO: | case ISD::SADDO: | ||||||||||||
case ISD::UADDO: | case ISD::UADDO: | ||||||||||||
case ISD::SSUBO: | case ISD::SSUBO: | ||||||||||||
case ISD::USUBO: | case ISD::USUBO: | ||||||||||||
Not Done ReplyInline ActionsXLEN is a RISC-V-specific term, referring to the size of its X registers jrtc27: XLEN is a RISC-V-specific term, referring to the size of its X registers | |||||||||||||
Oh, sorry; I didn't know that. AnnikaCodes: Oh, sorry; I didn't know that. | |||||||||||||
case ISD::SMULO: | case ISD::SMULO: | ||||||||||||
case ISD::UMULO: | case ISD::UMULO: | ||||||||||||
return LowerXALUO(Op, DAG); | return LowerXALUO(Op, DAG); | ||||||||||||
case ISD::SETCC: | case ISD::SETCC: | ||||||||||||
return LowerSETCC(Op, DAG); | return LowerSETCC(Op, DAG); | ||||||||||||
case ISD::SETCCCARRY: | case ISD::SETCCCARRY: | ||||||||||||
return LowerSETCCCARRY(Op, DAG); | return LowerSETCCCARRY(Op, DAG); | ||||||||||||
case ISD::SELECT: | case ISD::SELECT: | ||||||||||||
Show All 14 Lines | SDValue M68kTargetLowering::LowerOperation(SDValue Op, | ||||||||||||
case ISD::BlockAddress: | case ISD::BlockAddress: | ||||||||||||
return LowerBlockAddress(Op, DAG); | return LowerBlockAddress(Op, DAG); | ||||||||||||
case ISD::JumpTable: | case ISD::JumpTable: | ||||||||||||
return LowerJumpTable(Op, DAG); | return LowerJumpTable(Op, DAG); | ||||||||||||
case ISD::VASTART: | case ISD::VASTART: | ||||||||||||
return LowerVASTART(Op, DAG); | return LowerVASTART(Op, DAG); | ||||||||||||
case ISD::DYNAMIC_STACKALLOC: | case ISD::DYNAMIC_STACKALLOC: | ||||||||||||
return LowerDYNAMIC_STACKALLOC(Op, DAG); | return LowerDYNAMIC_STACKALLOC(Op, DAG); | ||||||||||||
case ISD::SHL_PARTS: | |||||||||||||
return LowerShiftLeftParts(Op, DAG); | |||||||||||||
case ISD::SRA_PARTS: | |||||||||||||
return LowerShiftRightParts(Op, DAG, true); | |||||||||||||
case ISD::SRL_PARTS: | |||||||||||||
return LowerShiftRightParts(Op, DAG, false); | |||||||||||||
} | } | ||||||||||||
} | } | ||||||||||||
bool M68kTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT, | bool M68kTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT, | ||||||||||||
SDValue C) const { | SDValue C) const { | ||||||||||||
// Shifts and add instructions in M68000 and M68010 support | // Shifts and add instructions in M68000 and M68010 support | ||||||||||||
// up to 32 bits, but mul only has 16-bit variant. So it's almost | // up to 32 bits, but mul only has 16-bit variant. So it's almost | ||||||||||||
// certainly beneficial to lower 8/16/32-bit mul to their | // certainly beneficial to lower 8/16/32-bit mul to their | ||||||||||||
▲ Show 20 Lines • Show All 1,869 Lines • ▼ Show 20 Lines | SDValue M68kTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op, | ||||||||||||
Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, DL, true), | Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, DL, true), | ||||||||||||
DAG.getIntPtrConstant(0, DL, true), SDValue(), DL); | DAG.getIntPtrConstant(0, DL, true), SDValue(), DL); | ||||||||||||
SDValue Ops[2] = {Result, Chain}; | SDValue Ops[2] = {Result, Chain}; | ||||||||||||
return DAG.getMergeValues(Ops, DL); | return DAG.getMergeValues(Ops, DL); | ||||||||||||
} | } | ||||||||||||
SDValue M68kTargetLowering::LowerShiftLeftParts(SDValue Op, | |||||||||||||
SelectionDAG &DAG) const { | |||||||||||||
SDLoc DL(Op); | |||||||||||||
SDValue Lo = Op.getOperand(0); | |||||||||||||
SDValue Hi = Op.getOperand(1); | |||||||||||||
SDValue Shamt = Op.getOperand(2); | |||||||||||||
EVT VT = Lo.getValueType(); | |||||||||||||
// if Shamt - register size < 0: // Shamt < register size | |||||||||||||
// Lo = Lo << Shamt | |||||||||||||
// Hi = (Hi << Shamt) | ((Lo >>u 1) >>u (register size - Shamt)) | |||||||||||||
"register size - ShAmt" -> "register size - 1 - ShAmt" right? craig.topper: "register size - ShAmt" -> "register size - 1 - ShAmt" right? | |||||||||||||
// else: | |||||||||||||
// Lo = 0 | |||||||||||||
// Hi = Lo << (Shamt - register size) | |||||||||||||
SDValue Zero = DAG.getConstant(0, DL, VT); | |||||||||||||
SDValue One = DAG.getConstant(1, DL, VT); | |||||||||||||
SDValue MinusRegisterSize = DAG.getConstant(-32, DL, VT); | |||||||||||||
SDValue RegisterSizeMinus1 = DAG.getConstant(32 - 1, DL, VT); | |||||||||||||
SDValue ShamtMinusRegisterSize = | |||||||||||||
DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize); | |||||||||||||
SDValue RegisterSizeMinus1Shamt = | |||||||||||||
This sub can be an xor. See D119411 I don't m68k, does it have an xor with immediate instruction? craig.topper: This sub can be an xor. See D119411
I don't m68k, does it have an xor with immediate… | |||||||||||||
DAG.getNode(ISD::SUB, DL, VT, RegisterSizeMinus1, Shamt); | |||||||||||||
SDValue LoTrue = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt); | |||||||||||||
SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, VT, Lo, One); | |||||||||||||
SDValue ShiftRightLo = | |||||||||||||
DAG.getNode(ISD::SRL, DL, VT, ShiftRight1Lo, RegisterSizeMinus1Shamt); | |||||||||||||
SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, Hi, Shamt); | |||||||||||||
SDValue HiTrue = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo); | |||||||||||||
SDValue HiFalse = DAG.getNode(ISD::SHL, DL, VT, Lo, ShamtMinusRegisterSize); | |||||||||||||
SDValue CC = DAG.getSetCC(DL, MVT::i8, ShamtMinusRegisterSize, Zero, ISD::SETLT); | |||||||||||||
Lint: Pre-merge checks clang-format: please reformat the code - SDValue CC = DAG.getSetCC(DL, MVT::i8, ShamtMinusRegisterSize, Zero, ISD::SETLT); + SDValue CC = + DAG.getSetCC(DL, MVT::i8, ShamtMinusRegisterSize, Zero, ISD::SETLT); Lint: Pre-merge checks: clang-format: please reformat the code
```
- SDValue CC = DAG.getSetCC(DL, MVT::i8… | |||||||||||||
Not Done ReplyInline Actions
That error seems result from here. 0x59616e: That error seems result from here. | |||||||||||||
Lo = DAG.getNode(ISD::SELECT, DL, VT, CC, LoTrue, Zero); | |||||||||||||
Hi = DAG.getNode(ISD::SELECT, DL, VT, CC, HiTrue, HiFalse); | |||||||||||||
SDValue Parts[2] = {Lo, Hi}; | |||||||||||||
return DAG.getMergeValues(Parts, DL); | |||||||||||||
This temporary array is unnecessary. You can write return DAG.getMergeValues({Lo, Hi}, DL); craig.topper: This temporary array is unnecessary. You can write
```
return DAG.getMergeValues({Lo, Hi}, DL)… | |||||||||||||
} | |||||||||||||
SDValue M68kTargetLowering::LowerShiftRightParts(SDValue Op, SelectionDAG &DAG, | |||||||||||||
bool IsSRA) const { | |||||||||||||
SDLoc DL(Op); | |||||||||||||
SDValue Lo = Op.getOperand(0); | |||||||||||||
SDValue Hi = Op.getOperand(1); | |||||||||||||
SDValue Shamt = Op.getOperand(2); | |||||||||||||
EVT VT = Lo.getValueType(); | |||||||||||||
// SRA expansion: | |||||||||||||
// if Shamt - register size < 0: // Shamt < register size | |||||||||||||
// Lo = (Lo >>u Shamt) | ((Hi << 1) << (register size - 1 - Shamt)) | |||||||||||||
// Hi = Hi >>s Shamt | |||||||||||||
// else: | |||||||||||||
// Lo = Hi >>s (Shamt - register size); | |||||||||||||
// Hi = Hi >>s (register size - 1) | |||||||||||||
// | |||||||||||||
// SRL expansion: | |||||||||||||
// if Shamt - register size < 0: // Shamt < register size | |||||||||||||
// Lo = (Lo >>u Shamt) | ((Hi << 1) << (register size - 1 - Shamt)) | |||||||||||||
// Hi = Hi >>u Shamt | |||||||||||||
// else: | |||||||||||||
// Lo = Hi >>u (Shamt - register size); | |||||||||||||
// Hi = 0; | |||||||||||||
Appreciate the explanations here :-) myhsu: Appreciate the explanations here :-) | |||||||||||||
unsigned ShiftRightOp = IsSRA ? ISD::SRA : ISD::SRL; | |||||||||||||
SDValue Zero = DAG.getConstant(0, DL, VT); | |||||||||||||
SDValue One = DAG.getConstant(1, DL, VT); | |||||||||||||
SDValue MinusRegisterSize = DAG.getConstant(-32, DL, VT); | |||||||||||||
SDValue RegisterSizeMinus1 = DAG.getConstant(32 - 1, DL, VT); | |||||||||||||
SDValue ShamtMinusRegisterSize = | |||||||||||||
DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize); | |||||||||||||
SDValue RegisterSizeMinus1Shamt = | |||||||||||||
DAG.getNode(ISD::SUB, DL, VT, RegisterSizeMinus1, Shamt); | |||||||||||||
SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, Lo, Shamt); | |||||||||||||
SDValue ShiftLeftHi1 = DAG.getNode(ISD::SHL, DL, VT, Hi, One); | |||||||||||||
SDValue ShiftLeftHi = | |||||||||||||
DAG.getNode(ISD::SHL, DL, VT, ShiftLeftHi1, RegisterSizeMinus1Shamt); | |||||||||||||
SDValue LoTrue = DAG.getNode(ISD::OR, DL, VT, ShiftRightLo, ShiftLeftHi); | |||||||||||||
SDValue HiTrue = DAG.getNode(ShiftRightOp, DL, VT, Hi, Shamt); | |||||||||||||
SDValue LoFalse = | |||||||||||||
DAG.getNode(ShiftRightOp, DL, VT, Hi, ShamtMinusRegisterSize); | |||||||||||||
SDValue HiFalse = | |||||||||||||
IsSRA ? DAG.getNode(ISD::SRA, DL, VT, Hi, RegisterSizeMinus1) : Zero; | |||||||||||||
SDValue CC = DAG.getSetCC(DL, MVT::i8, ShamtMinusRegisterSize, Zero, ISD::SETLT); | |||||||||||||
Lint: Pre-merge checks clang-format: please reformat the code - SDValue CC = DAG.getSetCC(DL, MVT::i8, ShamtMinusRegisterSize, Zero, ISD::SETLT); + SDValue CC = + DAG.getSetCC(DL, MVT::i8, ShamtMinusRegisterSize, Zero, ISD::SETLT); Lint: Pre-merge checks: clang-format: please reformat the code
```
- SDValue CC = DAG.getSetCC(DL, MVT::i8… | |||||||||||||
Lo = DAG.getNode(ISD::SELECT, DL, VT, CC, LoTrue, LoFalse); | |||||||||||||
...and here. 0x59616e: ...and here.
| |||||||||||||
Hi = DAG.getNode(ISD::SELECT, DL, VT, CC, HiTrue, HiFalse); | |||||||||||||
SDValue Parts[2] = {Lo, Hi}; | |||||||||||||
return DAG.getMergeValues(Parts, DL); | |||||||||||||
} | |||||||||||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||||||||
// DAG Combine | // DAG Combine | ||||||||||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||||||||
static SDValue getSETCC(M68k::CondCode Cond, SDValue CCR, const SDLoc &dl, | static SDValue getSETCC(M68k::CondCode Cond, SDValue CCR, const SDLoc &dl, | ||||||||||||
SelectionDAG &DAG) { | SelectionDAG &DAG) { | ||||||||||||
return DAG.getNode(M68kISD::SETCC, dl, MVT::i8, | return DAG.getNode(M68kISD::SETCC, dl, MVT::i8, | ||||||||||||
DAG.getConstant(Cond, dl, MVT::i8), CCR); | DAG.getConstant(Cond, dl, MVT::i8), CCR); | ||||||||||||
} | } | ||||||||||||
// When legalizing carry, we create carries via add X, -1 | // When legalizing carry, we create carries via add X, -1 | ||||||||||||
// If that comes from an actual carry, via setcc, we use the | // If that comes from an actual carry, via setcc, we use the | ||||||||||||
// carry directly. | // carry directly. | ||||||||||||
static SDValue combineCarryThroughADD(SDValue CCR) { | static SDValue combineCarryThroughADD(SDValue CCR) { | ||||||||||||
if (CCR.getOpcode() == M68kISD::ADD) { | if (CCR.getOpcode() == M68kISD::ADD) { | ||||||||||||
if (isAllOnesConstant(CCR.getOperand(1))) { | if (isAllOnesConstant(CCR.getOperand(1))) { | ||||||||||||
SDValue Carry = CCR.getOperand(0); | SDValue Carry = CCR.getOperand(0); | ||||||||||||
while (Carry.getOpcode() == ISD::TRUNCATE || | while (Carry.getOpcode() == ISD::TRUNCATE || | ||||||||||||
Carry.getOpcode() == ISD::ZERO_EXTEND || | Carry.getOpcode() == ISD::ZERO_EXTEND || | ||||||||||||
Carry.getOpcode() == ISD::SIGN_EXTEND || | Carry.getOpcode() == ISD::SIGN_EXTEND || | ||||||||||||
Carry.getOpcode() == ISD::ANY_EXTEND || | Carry.getOpcode() == ISD::ANY_EXTEND || | ||||||||||||
(Carry.getOpcode() == ISD::AND && | (Carry.getOpcode() == ISD::AND && | ||||||||||||
isOneConstant(Carry.getOperand(1)))) | isOneConstant(Carry.getOperand(1)))) | ||||||||||||
These other changes are because I ran clang-format on the file; it's syntactically the same. AnnikaCodes: These other changes are because I ran `clang-format` on the file; it's syntactically the same. | |||||||||||||
Not Done ReplyInline Actionsditto, please use clang-format-diff.py instead myhsu: ditto, please use clang-format-diff.py instead | |||||||||||||
Carry = Carry.getOperand(0); | Carry = Carry.getOperand(0); | ||||||||||||
if (Carry.getOpcode() == M68kISD::SETCC || | if (Carry.getOpcode() == M68kISD::SETCC || | ||||||||||||
Carry.getOpcode() == M68kISD::SETCC_CARRY) { | Carry.getOpcode() == M68kISD::SETCC_CARRY) { | ||||||||||||
if (Carry.getConstantOperandVal(0) == M68k::COND_CS) | if (Carry.getConstantOperandVal(0) == M68k::COND_CS) | ||||||||||||
return Carry.getOperand(1); | return Carry.getOperand(1); | ||||||||||||
} | } | ||||||||||||
} | } | ||||||||||||
} | } | ||||||||||||
▲ Show 20 Lines • Show All 154 Lines • Show Last 20 Lines |
clang-format not found in user’s local PATH; not linting file.