Daniel Sanders
2015-Mar-04 16:30 UTC
[LLVMdev] Inline Assembly: Memory constraints with offsets
> -----Original Message----- > From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu] > On Behalf Of Krzysztof Parzyszek > Sent: 03 March 2015 14:35 > To: llvmdev at cs.uiuc.edu > Subject: Re: [LLVMdev] Inline Assembly: Memory constraints with offsets > > On 3/3/2015 6:01 AM, Daniel Sanders wrote: > > Hi, > > > > I'm trying to implement the ZC inline assembly constraint for Mips. This > > constraint is a memory constraint that expands to an address with an > > offset (the range of the offset varies according to the subtarget), so > > the inline assembly in: > > > > int data[10]; > > > > void ZC(void) { > > > > asm volatile ("foo %0 %1" : : "ZC"(data[1]), "ZC"(data[2])); > > > > } > > > > Should expand to something like: > > > > foo 4($2) 8($2) > > > > At the moment, the best I can get is something like: > > > > foo 0($2) 0($3) > > > > with the offsets being added before the inline assembly. > > > > Does anyone have any suggestions as to how I can get the offset inside > > the inline assembly? > > How are you actually getting this to compile? I just built clang and > I'm getting an error: > > clang-3.6 -target mips -S mipsa.c > mipsa.c:4:33: error: invalid input constraint 'ZC' in asm > asm volatile ("foo %0 %1" : : "ZC"(data[1]), "ZC"(data[2])); > ^ > 1 error generated. > > > It doesn't seem that the function "validateAsmConstraint" in > tools/clang/lib/Basic/Targets.cpp handles "ZC" as a constraint. > > -KrzysztofPartial support for ZC is in my working copy at the moment. I've attached my WIP patches.> -- > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, > hosted by The Linux Foundation > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev-------------- next part -------------- A non-text attachment was scrubbed... Name: clang-implement-ZC.patch Type: application/octet-stream Size: 1177 bytes Desc: clang-implement-ZC.patch URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150304/e20afa8e/attachment.obj> -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-implement-ZC.patch Type: application/octet-stream Size: 975 bytes Desc: llvm-implement-ZC.patch URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150304/e20afa8e/attachment-0001.obj>
Krzysztof Parzyszek
2015-Mar-05 15:05 UTC
[LLVMdev] Inline Assembly: Memory constraints with offsets
On 3/4/2015 10:30 AM, Daniel Sanders wrote:> > Partial support for ZC is in my working copy at the moment. I've attached my WIP patches.Should have guessed that, ha. I've looked into this. My idea was to expand the single address operand of the inline-asm SDNode into two: base pointer and offset. I haven't found a place where all needed information would be readily available, and where the common code would do all the work based on some target-specific hook. Failing that, my last resort approach would be to have a pre-isel pass that expands the inline-asm, potentially changing the constraints to reflect the connection between the register and the constant input operands (needed for the asm-printer). Not sure if this is of any help. -Krzysztof -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Daniel Sanders
2015-Mar-09 10:22 UTC
[LLVMdev] Inline Assembly: Memory constraints with offsets
> From: Krzysztof Parzyszek [kparzysz at codeaurora.org] > On 3/4/2015 10:30 AM, Daniel Sanders wrote: > > > > Partial support for ZC is in my working copy at the moment. I've attached my WIP patches. > > Should have guessed that, ha. > > I've looked into this. My idea was to expand the single address operand > of the inline-asm SDNode into two: base pointer and offset. > > I haven't found a place where all needed information would be readily > available, and where the common code would do all the work based on some > target-specific hook. Failing that, my last resort approach would be to > have a pre-isel pass that expands the inline-asm, potentially changing > the constraints to reflect the connection between the register and the > constant input operands (needed for the asm-printer). > > Not sure if this is of any help. > > -Krzysztof > > -- > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, > hosted by The Linux FoundationI've had some luck with this. It turns out that the ISD::INLINE_ASM node has a flag operand corresponding to each operand in the source code. It's used for storing things like the matched operand number for the [0-9]+ constraints, the register class id for register constraints, etc. At first glance, the encoding looks full but it appears that when the lowest 3 bits are Kind_Mem (meaning it's a memory constraint), the upper 16-bits are never used. I've therefore used this gap to store a constraint ID which can then be inspected during instruction selection. The mapping from constraint string to constraint id is provided by a target specific hook with unmapped constraints causing a failure (currently an assertion but it should be llvm_unreachable). I now have the Mips 'ZC' constraint supporting 12-bit offsets while 'm' continues to lack support for offsets. This isn't the correct behaviour for 'ZC' or for 'm' but it does at least demonstrate that different memory constraints can now behave differently. My WIP patch is at http://reviews.llvm.org/D8160. It's going to be split up into multiple patches and the Mips portion is going to be corrected before I upstream it. I'll also check the clang tests to see if I've missed any supported constraints. There's a few odd target specific things in the current code so I've CC'd the code owners. I couldn't find a code owner for PowerPC or MSP430 in CODE_OWNERS.txt though. The Hexagon and X86 backends both had code that attempted to implement different behaviour for the 'o' and 'v' memory constraints but this code has been unused so far because the backend always received the code 'm'. I attempted to use the existing implementations for these but this causes test failures so I've left them behaving like 'm'. The AArch64, ARM, PowerPC, and SystemZ backends have tests for a few constraints that currently behave like 'm'. I assume that keeping the 'm' behaviour is ok for now. There's also a change to the MSP430 backend that should be non-functional but I ought to mention. The change is that the inline assembly flags are now i32 instead of a pointer-sized int. This is because it will attempt to store a 32-bit value in an i16 otherwise.