mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
X86: Rework inline asm integer register specification.
This is a new version of http://reviews.llvm.org/D10260. It turned out that when you specify an integer register in inline asm on x86 you get the register of the required type size back. That means that X86TargetLowering::getRegForInlineAsmConstraint() has to accept any of the integer registers and adapt its size to the given target size which may be any 8/16/32/64 bit sized type. Surprisingly that means given a constraint of "{ax}" and a type of MVT::F32 we need to return X86::EAX. This change makes this face explicit, the previous code seemed like working by accident because there it never returned an error once a register was found. On the other hand this rewrite allows to actually return errors for invalid situations like requesting an integer register for an i128 type. Related to rdar://21042280 Differential Revision: http://reviews.llvm.org/D10813 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241002 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
135
test/CodeGen/X86/asm-mismatched-types.ll
Normal file
135
test/CodeGen/X86/asm-mismatched-types.ll
Normal file
@@ -0,0 +1,135 @@
|
||||
; RUN: llc -o - %s -no-integrated-as | FileCheck %s
|
||||
target triple = "x86_64--"
|
||||
|
||||
; Allow to specify any of the 8/16/32/64 register names interchangeably in
|
||||
; constraints
|
||||
|
||||
; Produced by C-programs like this:
|
||||
; void foo(int p) { register int reg __asm__("r8") = p;
|
||||
; __asm__ __volatile__("# REG: %0" : : "r" (reg)); }
|
||||
|
||||
; CHECK-LABEL: reg64_as_32:
|
||||
; CHECK: # REG: %r8d
|
||||
define void @reg64_as_32(i32 %p) {
|
||||
call void asm sideeffect "# REG: $0", "{r8}"(i32 %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg64_as_32_float:
|
||||
; CHECK: # REG: %r8d
|
||||
define void @reg64_as_32_float(float %p) {
|
||||
call void asm sideeffect "# REG: $0", "{r8}"(float %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg64_as_16:
|
||||
; CHECK: # REG: %r9w
|
||||
define void @reg64_as_16(i16 %p) {
|
||||
call void asm sideeffect "# REG: $0", "{r9}"(i16 %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg64_as_8:
|
||||
; CHECK: # REG: %bpl
|
||||
define void @reg64_as_8(i8 %p) {
|
||||
call void asm sideeffect "# REG: $0", "{rbp}"(i8 %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg32_as_16:
|
||||
; CHECK: # REG: %r15w
|
||||
define void @reg32_as_16(i16 %p) {
|
||||
call void asm sideeffect "# REG: $0", "{r15d}"(i16 %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg32_as_8:
|
||||
; CHECK: # REG: %r12b
|
||||
define void @reg32_as_8(i8 %p) {
|
||||
call void asm sideeffect "# REG: $0", "{r12d}"(i8 %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg16_as_8:
|
||||
; CHECK: # REG: %cl
|
||||
define void @reg16_as_8(i8 %p) {
|
||||
call void asm sideeffect "# REG: $0", "{cx}"(i8 %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg32_as_64:
|
||||
; CHECK: # REG: %rbp
|
||||
define void @reg32_as_64(i64 %p) {
|
||||
call void asm sideeffect "# REG: $0", "{ebp}"(i64 %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg32_as_64_float:
|
||||
; CHECK: # REG: %rbp
|
||||
define void @reg32_as_64_float(double %p) {
|
||||
call void asm sideeffect "# REG: $0", "{ebp}"(double %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg16_as_64:
|
||||
; CHECK: # REG: %r13
|
||||
define void @reg16_as_64(i64 %p) {
|
||||
call void asm sideeffect "# REG: $0", "{r13w}"(i64 %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg16_as_64_float:
|
||||
; CHECK: # REG: %r13
|
||||
define void @reg16_as_64_float(double %p) {
|
||||
call void asm sideeffect "# REG: $0", "{r13w}"(double %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg8_as_64:
|
||||
; CHECK: # REG: %rax
|
||||
define void @reg8_as_64(i64 %p) {
|
||||
call void asm sideeffect "# REG: $0", "{al}"(i64 %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg8_as_64_float:
|
||||
; CHECK: # REG: %rax
|
||||
define void @reg8_as_64_float(double %p) {
|
||||
call void asm sideeffect "# REG: $0", "{al}"(double %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg16_as_32:
|
||||
; CHECK: # REG: %r11d
|
||||
define void @reg16_as_32(i32 %p) {
|
||||
call void asm sideeffect "# REG: $0", "{r11w}"(i32 %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg16_as_32_float:
|
||||
; CHECK: # REG: %r11d
|
||||
define void @reg16_as_32_float(float %p) {
|
||||
call void asm sideeffect "# REG: $0", "{r11w}"(float %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg8_as_32:
|
||||
; CHECK: # REG: %r9d
|
||||
define void @reg8_as_32(i32 %p) {
|
||||
call void asm sideeffect "# REG: $0", "{r9b}"(i32 %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg8_as_32_float:
|
||||
; CHECK: # REG: %r9d
|
||||
define void @reg8_as_32_float(float %p) {
|
||||
call void asm sideeffect "# REG: $0", "{r9b}"(float %p)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: reg8_as_16:
|
||||
; CHECK: # REG: %di
|
||||
define void @reg8_as_16(i16 %p) {
|
||||
call void asm sideeffect "# REG: $0", "{dil}"(i16 %p)
|
||||
ret void
|
||||
}
|
8
test/CodeGen/X86/asm-reject-reg-type-mismatch.ll
Normal file
8
test/CodeGen/X86/asm-reject-reg-type-mismatch.ll
Normal file
@@ -0,0 +1,8 @@
|
||||
; RUN: not llc -o /dev/null %s 2>&1 | FileCheck %s
|
||||
target triple = "x86_64--"
|
||||
|
||||
; CHECK: error: couldn't allocate output register for constraint '{ax}'
|
||||
define i128 @blup() {
|
||||
%v = tail call i128 asm "", "={ax},0"(i128 0)
|
||||
ret i128 %v
|
||||
}
|
Reference in New Issue
Block a user