llvm.org GIT mirror llvm / 64c8bcf
Merging r332444: ------------------------------------------------------------------------ r332444 | psmith | 2018-05-16 02:33:25 -0700 (Wed, 16 May 2018) | 20 lines [AArch64] Support "S" inline assembler constraint This patch re-introduces the "S" inline assembler constraint. This matches an absolute symbolic address or a label reference. The primary use case is asm("adrp %0, %1\n\t" "add %0, %0, :lo12:%1" : "=r"(addr) : "S"(&var)); I say re-introduces as it seems like "S" was implemented in the original AArch64 backend, but it looks like it wasn't carried forward to the merged backend. The original implementation had A and L modifiers that could be used to print ":lo12:" to the string. It looks like gcc doesn't use these and :lo12: is expected to be written in the inline assembly string so I've not implemented A and L. Clang already supports the S modifier. Fixes PR37180 Differential Revision: https://reviews.llvm.org/D46745 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_60@332644 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 2 years ago
3 changed file(s) with 45 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
296296
297297 Sym->print(O, MAI);
298298 printOffset(MO.getOffset(), O);
299 break;
300 }
301 case MachineOperand::MO_BlockAddress: {
302 MCSymbol *Sym = GetBlockAddressSymbol(MO.getBlockAddress());
303 Sym->print(O, MAI);
299304 break;
300305 }
301306 }
50655065
50665066 // Table of Constraints
50675067 // TODO: This is the current set of constraints supported by ARM for the
5068 // compiler, not all of them may make sense, e.g. S may be difficult to support.
5068 // compiler, not all of them may make sense.
50695069 //
50705070 // r - A general register
50715071 // w - An FP/SIMD register of some size in the range v0-v31
51255125 // currently handle addresses it is the same as 'r'.
51265126 case 'Q':
51275127 return C_Memory;
5128 case 'S': // A symbolic address
5129 return C_Other;
51285130 }
51295131 }
51305132 return TargetLowering::getConstraintType(Constraint);
52475249 Result = DAG.getRegister(AArch64::XZR, MVT::i64);
52485250 else
52495251 Result = DAG.getRegister(AArch64::WZR, MVT::i32);
5252 break;
5253 }
5254 case 'S': {
5255 // An absolute symbolic address or label reference.
5256 if (const GlobalAddressSDNode *GA = dyn_cast(Op)) {
5257 Result = DAG.getTargetGlobalAddress(GA->getGlobal(), SDLoc(Op),
5258 GA->getValueType(0));
5259 } else if (const BlockAddressSDNode *BA =
5260 dyn_cast(Op)) {
5261 Result =
5262 DAG.getTargetBlockAddress(BA->getBlockAddress(), BA->getValueType(0));
5263 } else if (const ExternalSymbolSDNode *ES =
5264 dyn_cast(Op)) {
5265 Result =
5266 DAG.getTargetExternalSymbol(ES->getSymbol(), ES->getValueType(0));
5267 } else
5268 return;
52505269 break;
52515270 }
52525271
0 ;RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+neon < %s | FileCheck %s
1 @var = global i32 0
2 define void @test_inline_constraint_S() {
3 ; CHECK-LABEL: test_inline_constraint_S:
4 call void asm sideeffect "adrp x0, $0", "S"(i32* @var)
5 call void asm sideeffect "add x0, x0, :lo12:$0", "S"(i32* @var)
6 ; CHECK: adrp x0, var
7 ; CHECK: add x0, x0, :lo12:var
8 ret void
9 }
10 define i32 @test_inline_constraint_S_label(i1 %in) {
11 ; CHECK-LABEL: test_inline_constraint_S_label:
12 call void asm sideeffect "adr x0, $0", "S"(i8* blockaddress(@test_inline_constraint_S_label, %loc))
13 ; CHECK: adr x0, .Ltmp{{[0-9]+}}
14 br i1 %in, label %loc, label %loc2
15 loc:
16 ret i32 0
17 loc2:
18 ret i32 42
19 }