-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Xtensa] Implement THREADPTR and DFPAccel Xtensa Options. #145543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -101,6 +101,7 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM, | |
|
||
setOperationAction(ISD::ConstantPool, PtrVT, Custom); | ||
setOperationAction(ISD::GlobalAddress, PtrVT, Custom); | ||
setOperationAction(ISD::GlobalTLSAddress, PtrVT, Custom); | ||
setOperationAction(ISD::BlockAddress, PtrVT, Custom); | ||
setOperationAction(ISD::JumpTable, PtrVT, Custom); | ||
|
||
|
@@ -919,6 +920,58 @@ SDValue XtensaTargetLowering::LowerGlobalAddress(SDValue Op, | |
return Res; | ||
} | ||
|
||
SDValue XtensaTargetLowering::LowerGlobalTLSAddress(SDValue Op, | ||
SelectionDAG &DAG) const { | ||
const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op); | ||
SDLoc DL(Op); | ||
auto PtrVT = Op.getValueType(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No auto |
||
const GlobalValue *GV = G->getGlobal(); | ||
|
||
if (DAG.getTarget().useEmulatedTLS()) | ||
return LowerToTLSEmulatedModel(G, DAG); | ||
|
||
TLSModel::Model model = getTargetMachine().getTLSModel(GV); | ||
|
||
if (!Subtarget.hasTHREADPTR()) { | ||
DAG.getContext()->diagnose(DiagnosticInfoUnsupported( | ||
DAG.getMachineFunction().getFunction(), "only emulated TLS supported", | ||
DL.getDebugLoc())); | ||
} | ||
|
||
if (model == TLSModel::LocalExec || model == TLSModel::InitialExec) { | ||
bool Priv = GV->isPrivateLinkage(GV->getLinkage()); | ||
MachineFunction &MF = DAG.getMachineFunction(); | ||
XtensaMachineFunctionInfo *XtensaFI = | ||
MF.getInfo<XtensaMachineFunctionInfo>(); | ||
unsigned LabelId = XtensaFI->createCPLabelId(); | ||
|
||
// Create a constant pool entry for the callee address | ||
XtensaConstantPoolValue *CPV = XtensaConstantPoolSymbol::Create( | ||
*DAG.getContext(), GV->getName().str().c_str(), LabelId, Priv, | ||
XtensaCP::TPOFF); | ||
|
||
// Get the address of the callee into a register | ||
SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4)); | ||
SDValue CPWrap = getAddrPCRel(CPAddr, DAG); | ||
SDValue Addr = DAG.getLoad( | ||
PtrVT, DL, DAG.getEntryNode(), CPWrap, | ||
MachinePointerInfo::getConstantPool(DAG.getMachineFunction())); | ||
|
||
SDValue TPRegister = DAG.getRegister(Xtensa::THREADPTR, MVT::i32); | ||
SDValue ThreadPointer = | ||
DAG.getNode(XtensaISD::RUR, DL, MVT::i32, TPRegister); | ||
|
||
return DAG.getNode(ISD::ADD, DL, PtrVT, ThreadPointer, Addr); | ||
} else { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No else after return |
||
DAG.getContext()->diagnose(DiagnosticInfoUnsupported( | ||
DAG.getMachineFunction().getFunction(), | ||
"only local-exec and initial-exec TLS mode supported", | ||
DL.getDebugLoc())); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In both of these error cases, you need to return a value There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This also implies there is missing test coverage for the error cases |
||
} | ||
|
||
return SDValue(); | ||
} | ||
|
||
SDValue XtensaTargetLowering::LowerBlockAddress(SDValue Op, | ||
SelectionDAG &DAG) const { | ||
BlockAddressSDNode *Node = cast<BlockAddressSDNode>(Op); | ||
|
@@ -1353,6 +1406,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op, | |
return LowerRETURNADDR(Op, DAG); | ||
case ISD::GlobalAddress: | ||
return LowerGlobalAddress(Op, DAG); | ||
case ISD::GlobalTLSAddress: | ||
return LowerGlobalTLSAddress(Op, DAG); | ||
case ISD::BlockAddress: | ||
return LowerBlockAddress(Op, DAG); | ||
case ISD::JumpTable: | ||
|
@@ -1406,6 +1461,8 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const { | |
return "XtensaISD::RET"; | ||
case XtensaISD::RETW: | ||
return "XtensaISD::RETW"; | ||
case XtensaISD::RUR: | ||
return "XtensaISD::RUR"; | ||
case XtensaISD::SELECT_CC: | ||
return "XtensaISD::SELECT_CC"; | ||
case XtensaISD::SRCL: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 | ||
; RUN: llc -mtriple=xtensa -mattr=+threadptr -disable-block-placement -verify-machineinstrs < %s \ | ||
; RUN: | FileCheck %s | ||
|
||
@i = external thread_local global i32 | ||
|
||
define i32 @f() { | ||
; CHECK-LABEL: f: | ||
; CHECK: .cfi_startproc | ||
; CHECK-NEXT: # %bb.0: # %entry | ||
; CHECK-NEXT: l32r a8, .LCPI0_0 | ||
; CHECK-NEXT: rur a9, threadptr | ||
; CHECK-NEXT: add a8, a9, a8 | ||
; CHECK-NEXT: l32i a2, a8, 0 | ||
; CHECK-NEXT: ret | ||
entry: | ||
%tmp1 = load i32, ptr @i | ||
ret i32 %tmp1 | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5 | ||
# RUN: llvm-mc -triple=xtensa -mattr=+dfpaccel -disassemble %s | FileCheck -check-prefixes=CHECK-DFPACCEL %s | ||
# RUN: not llvm-mc -triple=xtensa -disassemble %s 2>&1 | FileCheck --implicit-check-not=warning: -check-prefixes=CHECK-CORE %s | ||
|
||
## Verify that binary code is correctly disassembled with | ||
## DFPACCEL option enabled. Also verify that dissasembling without | ||
## DFPACCEL option generates warnings. | ||
|
||
[0xa0,0x3e,0xe3] | ||
# CHECK-DFPACCEL: rur a3, f64r_lo | ||
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding | ||
|
||
[0xb0,0x3e,0xe3] | ||
# CHECK-DFPACCEL: rur a3, f64r_hi | ||
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding | ||
|
||
[0xc0,0x3e,0xe3] | ||
# CHECK-DFPACCEL: rur a3, f64s | ||
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5 | ||
# RUN: llvm-mc -triple=xtensa -mattr=+threadptr -disassemble %s | FileCheck -check-prefixes=CHECK-THREADPTR %s | ||
# RUN: not llvm-mc -triple=xtensa -disassemble %s 2>&1 | FileCheck --implicit-check-not=warning: -check-prefixes=CHECK-CORE %s | ||
|
||
## Verify that binary code is correctly disassembled with | ||
## THREADPTR option enabled. Also verify that dissasembling without | ||
## THREADPTR option generates warnings. | ||
|
||
[0x70,0x3e,0xe3] | ||
# CHECK-THREADPTR: rur a3, threadptr | ||
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+dfpaccel \ | ||
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s | ||
|
||
.align 4 | ||
LBL0: | ||
|
||
# CHECK-INST: rur a3, f64r_lo | ||
# CHECK: encoding: [0xa0,0x3e,0xe3] | ||
rur a3, f64r_lo | ||
|
||
# CHECK-INST: rur a3, f64r_lo | ||
# CHECK: encoding: [0xa0,0x3e,0xe3] | ||
rur a3, 234 | ||
|
||
# CHECK-INST: rur a3, f64r_lo | ||
# CHECK: encoding: [0xa0,0x3e,0xe3] | ||
rur.f64r_lo a3 | ||
|
||
# CHECK-INST: wur a3, f64r_lo | ||
# CHECK: encoding: [0x30,0xea,0xf3] | ||
wur a3, f64r_lo | ||
|
||
# CHECK-INST: rur a3, f64r_hi | ||
# CHECK: encoding: [0xb0,0x3e,0xe3] | ||
rur a3, f64r_hi | ||
|
||
# CHECK-INST: rur a3, f64r_hi | ||
# CHECK: encoding: [0xb0,0x3e,0xe3] | ||
rur a3, 235 | ||
|
||
# CHECK-INST: rur a3, f64r_hi | ||
# CHECK: encoding: [0xb0,0x3e,0xe3] | ||
rur.f64r_hi a3 | ||
|
||
# CHECK-INST: wur a3, f64r_hi | ||
# CHECK: encoding: [0x30,0xeb,0xf3] | ||
wur a3, f64r_hi | ||
|
||
# CHECK-INST: rur a3, f64s | ||
# CHECK: encoding: [0xc0,0x3e,0xe3] | ||
rur a3, f64s | ||
|
||
# CHECK-INST: rur a3, f64s | ||
# CHECK: encoding: [0xc0,0x3e,0xe3] | ||
rur a3, 236 | ||
|
||
# CHECK-INST: rur a3, f64s | ||
# CHECK: encoding: [0xc0,0x3e,0xe3] | ||
rur.f64s a3 | ||
|
||
# CHECK-INST: wur a3, f64s | ||
# CHECK: encoding: [0x30,0xec,0xf3] | ||
wur a3, f64s |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+threadptr \ | ||
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s | ||
|
||
.align 4 | ||
LBL0: | ||
|
||
# CHECK-INST: rur a3, threadptr | ||
# CHECK: encoding: [0x70,0x3e,0xe3] | ||
rur a3, threadptr | ||
|
||
# CHECK-INST: rur a3, threadptr | ||
# CHECK: encoding: [0x70,0x3e,0xe3] | ||
rur a3, 231 | ||
|
||
# CHECK-INST: rur a3, threadptr | ||
# CHECK: encoding: [0x70,0x3e,0xe3] | ||
rur.threadptr a3 | ||
|
||
# CHECK-INST: wur a3, threadptr | ||
# CHECK: encoding: [0x30,0xe7,0xf3] | ||
wur a3, threadptr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no else after return
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I rewrote the function code.