You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.207
Former-commit-id: 3b152f462918d427ce18620a2cbe4f8b79650449
This commit is contained in:
parent
8e12397d70
commit
eb85e2fc17
@ -1,223 +0,0 @@
|
||||
; RUN: llc -march=mips -relocation-model=static -mattr=+soft-float < %s | FileCheck --check-prefixes=ALL,SYM32,O32,O32BE %s
|
||||
; RUN: llc -march=mipsel -relocation-model=static -mattr=+soft-float < %s | FileCheck --check-prefixes=ALL,SYM32,O32,O32LE %s
|
||||
|
||||
; RUN-TODO: llc -march=mips64 -relocation-model=static -mattr=+soft-float -target-abi o32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
|
||||
; RUN-TODO: llc -march=mips64el -relocation-model=static -mattr=+soft-float -target-abi o32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
|
||||
|
||||
; RUN: llc -march=mips64 -relocation-model=static -mattr=+soft-float -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,NEW %s
|
||||
; RUN: llc -march=mips64el -relocation-model=static -mattr=+soft-float -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,NEW %s
|
||||
|
||||
; RUN: llc -march=mips64 -relocation-model=static -mattr=+soft-float -target-abi n64 < %s | FileCheck --check-prefixes=ALL,SYM64,NEW %s
|
||||
; RUN: llc -march=mips64el -relocation-model=static -mattr=+soft-float -target-abi n64 < %s | FileCheck --check-prefixes=ALL,SYM64,NEW %s
|
||||
|
||||
; Test the floating point arguments for all ABI's and byte orders as specified
|
||||
; by section 5 of MD00305 (MIPS ABIs Described).
|
||||
;
|
||||
; N32/N64 are identical in this area so their checks have been combined into
|
||||
; the 'NEW' prefix (the N stands for New).
|
||||
|
||||
@bytes = global [11 x i8] zeroinitializer
|
||||
@dwords = global [11 x i64] zeroinitializer
|
||||
@floats = global [11 x float] zeroinitializer
|
||||
@doubles = global [11 x double] zeroinitializer
|
||||
|
||||
define void @double_args(double %a, double %b, double %c, double %d, double %e,
|
||||
double %f, double %g, double %h, double %i) nounwind {
|
||||
entry:
|
||||
%0 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 1
|
||||
store volatile double %a, double* %0
|
||||
%1 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 2
|
||||
store volatile double %b, double* %1
|
||||
%2 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 3
|
||||
store volatile double %c, double* %2
|
||||
%3 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 4
|
||||
store volatile double %d, double* %3
|
||||
%4 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 5
|
||||
store volatile double %e, double* %4
|
||||
%5 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 6
|
||||
store volatile double %f, double* %5
|
||||
%6 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 7
|
||||
store volatile double %g, double* %6
|
||||
%7 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 8
|
||||
store volatile double %h, double* %7
|
||||
%8 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 9
|
||||
store volatile double %i, double* %8
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: double_args:
|
||||
; We won't test the way the global address is calculated in this test. This is
|
||||
; just to get the register number for the other checks.
|
||||
; SYM32-DAG: addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(doubles)
|
||||
; SYM64-DAG: daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(doubles)
|
||||
|
||||
; The first four arguments are the same in O32/N32/N64.
|
||||
; The first argument is floating point but soft-float is enabled so floating
|
||||
; point registers are not used.
|
||||
; O32-DAG: sw $4, 8([[R2]])
|
||||
; O32-DAG: sw $5, 12([[R2]])
|
||||
; NEW-DAG: sd $4, 8([[R2]])
|
||||
|
||||
; O32-DAG: sw $6, 16([[R2]])
|
||||
; O32-DAG: sw $7, 20([[R2]])
|
||||
; NEW-DAG: sd $5, 16([[R2]])
|
||||
|
||||
; O32 has run out of argument registers and starts using the stack
|
||||
; O32-DAG: lw [[R3:\$([0-9]+|gp)]], 16($sp)
|
||||
; O32-DAG: lw [[R4:\$([0-9]+|gp)]], 20($sp)
|
||||
; O32-DAG: sw [[R3]], 24([[R2]])
|
||||
; O32-DAG: sw [[R4]], 28([[R2]])
|
||||
; NEW-DAG: sd $6, 24([[R2]])
|
||||
|
||||
; O32-DAG: lw [[R3:\$([0-9]+|gp)]], 24($sp)
|
||||
; O32-DAG: lw [[R4:\$([0-9]+|gp)]], 28($sp)
|
||||
; O32-DAG: sw [[R3]], 32([[R2]])
|
||||
; O32-DAG: sw [[R4]], 36([[R2]])
|
||||
; NEW-DAG: sd $7, 32([[R2]])
|
||||
|
||||
; O32-DAG: lw [[R3:\$([0-9]+|gp)]], 32($sp)
|
||||
; O32-DAG: lw [[R4:\$([0-9]+|gp)]], 36($sp)
|
||||
; O32-DAG: sw [[R3]], 40([[R2]])
|
||||
; O32-DAG: sw [[R4]], 44([[R2]])
|
||||
; NEW-DAG: sd $8, 40([[R2]])
|
||||
|
||||
; O32-DAG: lw [[R3:\$([0-9]+|gp)]], 40($sp)
|
||||
; O32-DAG: lw [[R4:\$([0-9]+|gp)]], 44($sp)
|
||||
; O32-DAG: sw [[R3]], 48([[R2]])
|
||||
; O32-DAG: sw [[R4]], 52([[R2]])
|
||||
; NEW-DAG: sd $9, 48([[R2]])
|
||||
|
||||
; O32-DAG: lw [[R3:\$([0-9]+|gp)]], 48($sp)
|
||||
; O32-DAG: lw [[R4:\$([0-9]+|gp)]], 52($sp)
|
||||
; O32-DAG: sw [[R3]], 56([[R2]])
|
||||
; O32-DAG: sw [[R4]], 60([[R2]])
|
||||
; NEW-DAG: sd $10, 56([[R2]])
|
||||
|
||||
; N32/N64 have run out of registers and starts using the stack too
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 56($sp)
|
||||
; O32-DAG: lw [[R4:\$[0-9]+]], 60($sp)
|
||||
; O32-DAG: sw [[R3]], 64([[R2]])
|
||||
; O32-DAG: sw [[R4]], 68([[R2]])
|
||||
; NEW-DAG: ld [[R3:\$[0-9]+]], 0($sp)
|
||||
; NEW-DAG: sd $11, 64([[R2]])
|
||||
|
||||
define void @float_args(float %a, float %b, float %c, float %d, float %e,
|
||||
float %f, float %g, float %h, float %i, float %j)
|
||||
nounwind {
|
||||
entry:
|
||||
%0 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 1
|
||||
store volatile float %a, float* %0
|
||||
%1 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 2
|
||||
store volatile float %b, float* %1
|
||||
%2 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 3
|
||||
store volatile float %c, float* %2
|
||||
%3 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 4
|
||||
store volatile float %d, float* %3
|
||||
%4 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 5
|
||||
store volatile float %e, float* %4
|
||||
%5 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 6
|
||||
store volatile float %f, float* %5
|
||||
%6 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 7
|
||||
store volatile float %g, float* %6
|
||||
%7 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 8
|
||||
store volatile float %h, float* %7
|
||||
%8 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 9
|
||||
store volatile float %i, float* %8
|
||||
%9 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 10
|
||||
store volatile float %j, float* %9
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: float_args:
|
||||
; We won't test the way the global address is calculated in this test. This is
|
||||
; just to get the register number for the other checks.
|
||||
; SYM32-DAG: addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(floats)
|
||||
; SYM64-DAG: daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(floats)
|
||||
|
||||
; The first four arguments are the same in O32/N32/N64.
|
||||
; The first argument is floating point but soft-float is enabled so floating
|
||||
; point registers are not used.
|
||||
; MD00305 and GCC disagree on this one. MD00305 says that floats are treated
|
||||
; as 8-byte aligned and occupy two slots on O32. GCC is treating them as 4-byte
|
||||
; aligned and occupying one slot. We'll use GCC's definition.
|
||||
; ALL-DAG: sw $4, 4([[R2]])
|
||||
; ALL-DAG: sw $5, 8([[R2]])
|
||||
; ALL-DAG: sw $6, 12([[R2]])
|
||||
; ALL-DAG: sw $7, 16([[R2]])
|
||||
|
||||
; O32 has run out of argument registers and starts using the stack
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 16($sp)
|
||||
; O32-DAG: sw [[R3]], 20([[R2]])
|
||||
; NEW-DAG: sw $8, 20([[R2]])
|
||||
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 20($sp)
|
||||
; O32-DAG: sw [[R3]], 24([[R2]])
|
||||
; NEW-DAG: sw $9, 24([[R2]])
|
||||
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 24($sp)
|
||||
; O32-DAG: sw [[R3]], 28([[R2]])
|
||||
; NEW-DAG: sw $10, 28([[R2]])
|
||||
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 28($sp)
|
||||
; O32-DAG: sw [[R3]], 32([[R2]])
|
||||
; NEW-DAG: sw $11, 32([[R2]])
|
||||
|
||||
; N32/N64 have run out of registers and start using the stack too
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 32($sp)
|
||||
; O32-DAG: sw [[R3]], 36([[R2]])
|
||||
; NEW-DAG: lw [[R3:\$[0-9]+]], 0($sp)
|
||||
; NEW-DAG: sw [[R3]], 36([[R2]])
|
||||
|
||||
define void @double_arg2(i8 %a, double %b) nounwind {
|
||||
entry:
|
||||
%0 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 1
|
||||
store volatile i8 %a, i8* %0
|
||||
%1 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 1
|
||||
store volatile double %b, double* %1
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: double_arg2:
|
||||
; We won't test the way the global address is calculated in this test. This is
|
||||
; just to get the register number for the other checks.
|
||||
; SYM32-DAG: addiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
|
||||
; SYM64-DAG: daddiu [[R1:\$[0-9]]], ${{[0-9]+}}, %lo(bytes)
|
||||
; SYM32-DAG: addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(doubles)
|
||||
; SYM64-DAG: daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(doubles)
|
||||
|
||||
; The first four arguments are the same in O32/N32/N64.
|
||||
; The first argument isn't floating point so floating point registers are not
|
||||
; used.
|
||||
; The second slot is insufficiently aligned for double on O32 so it is skipped.
|
||||
; Also, double occupies two slots on O32 and only one for N32/N64.
|
||||
; ALL-DAG: sb $4, 1([[R1]])
|
||||
; O32-DAG: sw $6, 8([[R2]])
|
||||
; O32-DAG: sw $7, 12([[R2]])
|
||||
; NEW-DAG: sd $5, 8([[R2]])
|
||||
|
||||
define void @float_arg2(i8 signext %a, float %b) nounwind {
|
||||
entry:
|
||||
%0 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 1
|
||||
store volatile i8 %a, i8* %0
|
||||
%1 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 1
|
||||
store volatile float %b, float* %1
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: float_arg2:
|
||||
; We won't test the way the global address is calculated in this test. This is
|
||||
; just to get the register number for the other checks.
|
||||
; SYM32-DAG: addiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
|
||||
; SYM64-DAG: daddiu [[R1:\$[0-9]]], ${{[0-9]+}}, %lo(bytes)
|
||||
; SYM32-DAG: addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(floats)
|
||||
; SYM64-DAG: daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(floats)
|
||||
|
||||
|
||||
; The first four arguments are the same in O32/N32/N64.
|
||||
; The first argument isn't floating point so floating point registers are not
|
||||
; used.
|
||||
; MD00305 and GCC disagree on this one. MD00305 says that floats are treated
|
||||
; as 8-byte aligned and occupy two slots on O32. GCC is treating them as 4-byte
|
||||
; aligned and occupying one slot. We'll use GCC's definition.
|
||||
; ALL-DAG: sb $4, 1([[R1]])
|
||||
; ALL-DAG: sw $5, 4([[R2]])
|
@ -1,51 +0,0 @@
|
||||
; RUN: llc -march=mips64 -relocation-model=static -mattr=+soft-float -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32 %s
|
||||
; RUN: llc -march=mips64el -relocation-model=static -mattr=+soft-float -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32 %s
|
||||
|
||||
; RUN: llc -march=mips64 -relocation-model=static -mattr=+soft-float -target-abi n64 < %s | FileCheck --check-prefixes=ALL,SYM64 %s
|
||||
; RUN: llc -march=mips64el -relocation-model=static -mattr=+soft-float -target-abi n64 < %s | FileCheck --check-prefixes=ALL,SYM64 %s
|
||||
|
||||
; Test the fp128 arguments for all ABI's and byte orders as specified
|
||||
; by section 2 of the MIPSpro N32 Handbook.
|
||||
;
|
||||
; O32 is not tested because long double is the same as double on O32.
|
||||
|
||||
@ldoubles = global [11 x fp128] zeroinitializer
|
||||
|
||||
define void @ldouble_args(fp128 %a, fp128 %b, fp128 %c, fp128 %d, fp128 %e) nounwind {
|
||||
entry:
|
||||
%0 = getelementptr [11 x fp128], [11 x fp128]* @ldoubles, i32 0, i32 1
|
||||
store volatile fp128 %a, fp128* %0
|
||||
%1 = getelementptr [11 x fp128], [11 x fp128]* @ldoubles, i32 0, i32 2
|
||||
store volatile fp128 %b, fp128* %1
|
||||
%2 = getelementptr [11 x fp128], [11 x fp128]* @ldoubles, i32 0, i32 3
|
||||
store volatile fp128 %c, fp128* %2
|
||||
%3 = getelementptr [11 x fp128], [11 x fp128]* @ldoubles, i32 0, i32 4
|
||||
store volatile fp128 %d, fp128* %3
|
||||
%4 = getelementptr [11 x fp128], [11 x fp128]* @ldoubles, i32 0, i32 5
|
||||
store volatile fp128 %e, fp128* %4
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: ldouble_args:
|
||||
; We won't test the way the global address is calculated in this test. This is
|
||||
; just to get the register number for the other checks.
|
||||
; SYM32-DAG: addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(ldoubles)
|
||||
; SYM64-DAG: daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(ldoubles)
|
||||
|
||||
; The first four arguments are the same in N32/N64.
|
||||
; The first argument is floating point but soft-float is enabled so floating
|
||||
; point registers are not used.
|
||||
; ALL-DAG: sd $4, 16([[R2]])
|
||||
; ALL-DAG: sd $5, 24([[R2]])
|
||||
; ALL-DAG: sd $6, 32([[R2]])
|
||||
; ALL-DAG: sd $7, 40([[R2]])
|
||||
; ALL-DAG: sd $8, 48([[R2]])
|
||||
; ALL-DAG: sd $9, 56([[R2]])
|
||||
; ALL-DAG: sd $10, 64([[R2]])
|
||||
; ALL-DAG: sd $11, 72([[R2]])
|
||||
|
||||
; N32/N64 have run out of registers and starts using the stack too
|
||||
; ALL-DAG: ld [[R3:\$[0-9]+]], 0($sp)
|
||||
; ALL-DAG: ld [[R4:\$[0-9]+]], 8($sp)
|
||||
; ALL-DAG: sd [[R3]], 80([[R2]])
|
||||
; ALL-DAG: sd [[R4]], 88([[R2]])
|
@ -1,161 +0,0 @@
|
||||
; RUN: llc -march=mips -relocation-model=static < %s | FileCheck --check-prefixes=ALL,SYM32,O32,O32BE %s
|
||||
; RUN: llc -march=mipsel -relocation-model=static < %s | FileCheck --check-prefixes=ALL,SYM32,O32,O32LE %s
|
||||
|
||||
; RUN-TODO: llc -march=mips64 -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
|
||||
; RUN-TODO: llc -march=mips64el -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
|
||||
|
||||
; RUN: llc -march=mips64 -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,N32,NEW,NEWBE %s
|
||||
; RUN: llc -march=mips64el -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,N32,NEW,NEWLE %s
|
||||
|
||||
; RUN: llc -march=mips64 -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,SYM64,N64,NEW,NEWBE %s
|
||||
; RUN: llc -march=mips64el -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,SYM64,N64,NEW,NEWLE %s
|
||||
|
||||
; Test the effect of varargs on floating point types in the non-variable part
|
||||
; of the argument list as specified by section 2 of the MIPSpro N32 Handbook.
|
||||
;
|
||||
; N32/N64 are almost identical in this area so many of their checks have been
|
||||
; combined into the 'NEW' prefix (the N stands for New).
|
||||
;
|
||||
; On O32, varargs prevents all FPU argument register usage. This contradicts
|
||||
; the N32 handbook, but agrees with the SYSV ABI and GCC's behaviour.
|
||||
|
||||
@floats = global [11 x float] zeroinitializer
|
||||
@doubles = global [11 x double] zeroinitializer
|
||||
|
||||
define void @double_args(double %a, ...)
|
||||
nounwind {
|
||||
entry:
|
||||
%0 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 1
|
||||
store volatile double %a, double* %0
|
||||
|
||||
%ap = alloca i8*
|
||||
%ap2 = bitcast i8** %ap to i8*
|
||||
call void @llvm.va_start(i8* %ap2)
|
||||
%b = va_arg i8** %ap, double
|
||||
%1 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 2
|
||||
store volatile double %b, double* %1
|
||||
call void @llvm.va_end(i8* %ap2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: double_args:
|
||||
; We won't test the way the global address is calculated in this test. This is
|
||||
; just to get the register number for the other checks.
|
||||
; SYM32-DAG: addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(doubles)
|
||||
; SYM64-DAG: daddiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(doubles)
|
||||
|
||||
; O32 forbids using floating point registers for the non-variable portion.
|
||||
; N32/N64 allow it.
|
||||
; O32BE-DAG: mtc1 $5, [[FTMP1:\$f[0-9]*[02468]+]]
|
||||
; O32BE-DAG: mtc1 $4, [[FTMP2:\$f[0-9]*[13579]+]]
|
||||
; O32LE-DAG: mtc1 $4, [[FTMP1:\$f[0-9]*[02468]+]]
|
||||
; O32LE-DAG: mtc1 $5, [[FTMP2:\$f[0-9]*[13579]+]]
|
||||
; O32-DAG: sdc1 [[FTMP1]], 8([[R2]])
|
||||
; NEW-DAG: sdc1 $f12, 8([[R2]])
|
||||
|
||||
; The varargs portion is dumped to stack
|
||||
; O32-DAG: sw $6, 16($sp)
|
||||
; O32-DAG: sw $7, 20($sp)
|
||||
; NEW-DAG: sd $5, 8($sp)
|
||||
; NEW-DAG: sd $6, 16($sp)
|
||||
; NEW-DAG: sd $7, 24($sp)
|
||||
; NEW-DAG: sd $8, 32($sp)
|
||||
; NEW-DAG: sd $9, 40($sp)
|
||||
; NEW-DAG: sd $10, 48($sp)
|
||||
; NEW-DAG: sd $11, 56($sp)
|
||||
|
||||
; Get the varargs pointer
|
||||
; O32 has 4 bytes padding, 4 bytes for the varargs pointer, and 8 bytes reserved
|
||||
; for arguments 1 and 2.
|
||||
; N32/N64 has 8 bytes for the varargs pointer, and no reserved area.
|
||||
; O32-DAG: addiu [[VAPTR:\$[0-9]+]], $sp, 16
|
||||
; O32-DAG: sw [[VAPTR]], 4($sp)
|
||||
; N32-DAG: addiu [[VAPTR:\$[0-9]+]], $sp, 8
|
||||
; N32-DAG: sw [[VAPTR]], 4($sp)
|
||||
; N64-DAG: daddiu [[VAPTR:\$[0-9]+]], $sp, 8
|
||||
; N64-DAG: sd [[VAPTR]], 0($sp)
|
||||
|
||||
; Increment the pointer then get the varargs arg
|
||||
; LLVM will rebind the load to the stack pointer instead of the varargs pointer
|
||||
; during lowering. This is fine and doesn't change the behaviour.
|
||||
; O32-DAG: addiu [[VAPTR]], [[VAPTR]], 8
|
||||
; O32-DAG: sw [[VAPTR]], 4($sp)
|
||||
; N32-DAG: addiu [[VAPTR]], [[VAPTR]], 8
|
||||
; N32-DAG: sw [[VAPTR]], 4($sp)
|
||||
; N64-DAG: daddiu [[VAPTR]], [[VAPTR]], 8
|
||||
; N64-DAG: sd [[VAPTR]], 0($sp)
|
||||
; O32-DAG: ldc1 [[FTMP1:\$f[0-9]+]], 16($sp)
|
||||
; NEW-DAG: ldc1 [[FTMP1:\$f[0-9]+]], 8($sp)
|
||||
; ALL-DAG: sdc1 [[FTMP1]], 16([[R2]])
|
||||
|
||||
define void @float_args(float %a, ...) nounwind {
|
||||
entry:
|
||||
%0 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 1
|
||||
store volatile float %a, float* %0
|
||||
|
||||
%ap = alloca i8*
|
||||
%ap2 = bitcast i8** %ap to i8*
|
||||
call void @llvm.va_start(i8* %ap2)
|
||||
%b = va_arg i8** %ap, float
|
||||
%1 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 2
|
||||
store volatile float %b, float* %1
|
||||
call void @llvm.va_end(i8* %ap2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: float_args:
|
||||
; We won't test the way the global address is calculated in this test. This is
|
||||
; just to get the register number for the other checks.
|
||||
; SYM32-DAG: addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(floats)
|
||||
; SYM64-DAG: daddiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(floats)
|
||||
|
||||
; The first four arguments are the same in O32/N32/N64.
|
||||
; The non-variable portion should be unaffected.
|
||||
; O32-DAG: sw $4, 4([[R2]])
|
||||
; NEW-DAG: swc1 $f12, 4([[R2]])
|
||||
|
||||
; The varargs portion is dumped to stack
|
||||
; O32-DAG: sw $5, 12($sp)
|
||||
; O32-DAG: sw $6, 16($sp)
|
||||
; O32-DAG: sw $7, 20($sp)
|
||||
; NEW-DAG: sd $5, 8($sp)
|
||||
; NEW-DAG: sd $6, 16($sp)
|
||||
; NEW-DAG: sd $7, 24($sp)
|
||||
; NEW-DAG: sd $8, 32($sp)
|
||||
; NEW-DAG: sd $9, 40($sp)
|
||||
; NEW-DAG: sd $10, 48($sp)
|
||||
; NEW-DAG: sd $11, 56($sp)
|
||||
|
||||
; Get the varargs pointer
|
||||
; O32 has 4 bytes padding, 4 bytes for the varargs pointer, and should have 8
|
||||
; bytes reserved for arguments 1 and 2 (the first float arg) but as discussed in
|
||||
; arguments-float.ll, GCC doesn't agree with MD00305 and treats floats as 4
|
||||
; bytes so we only have 12 bytes total.
|
||||
; N32/N64 has 8 bytes for the varargs pointer, and no reserved area.
|
||||
; O32-DAG: addiu [[VAPTR:\$[0-9]+]], $sp, 12
|
||||
; O32-DAG: sw [[VAPTR]], 4($sp)
|
||||
; N32-DAG: addiu [[VAPTR:\$[0-9]+]], $sp, 8
|
||||
; N32-DAG: sw [[VAPTR]], 4($sp)
|
||||
; N64-DAG: daddiu [[VAPTR:\$[0-9]+]], $sp, 8
|
||||
; N64-DAG: sd [[VAPTR]], 0($sp)
|
||||
|
||||
; Increment the pointer then get the varargs arg
|
||||
; LLVM will rebind the load to the stack pointer instead of the varargs pointer
|
||||
; during lowering. This is fine and doesn't change the behaviour.
|
||||
; Also, in big-endian mode the offset must be increased by 4 to retrieve the
|
||||
; correct half of the argument slot.
|
||||
;
|
||||
; O32-DAG: addiu [[VAPTR]], [[VAPTR]], 4
|
||||
; O32-DAG: sw [[VAPTR]], 4($sp)
|
||||
; N32-DAG: addiu [[VAPTR]], [[VAPTR]], 8
|
||||
; N32-DAG: sw [[VAPTR]], 4($sp)
|
||||
; N64-DAG: daddiu [[VAPTR]], [[VAPTR]], 8
|
||||
; N64-DAG: sd [[VAPTR]], 0($sp)
|
||||
; O32-DAG: lwc1 [[FTMP1:\$f[0-9]+]], 12($sp)
|
||||
; NEWLE-DAG: lwc1 [[FTMP1:\$f[0-9]+]], 8($sp)
|
||||
; NEWBE-DAG: lwc1 [[FTMP1:\$f[0-9]+]], 12($sp)
|
||||
; ALL-DAG: swc1 [[FTMP1]], 8([[R2]])
|
||||
|
||||
declare void @llvm.va_start(i8*)
|
||||
declare void @llvm.va_copy(i8*, i8*)
|
||||
declare void @llvm.va_end(i8*)
|
@ -1,211 +0,0 @@
|
||||
; RUN: llc -march=mips -relocation-model=static < %s | FileCheck --check-prefixes=ALL,SYM32,O32,O32BE %s
|
||||
; RUN: llc -march=mipsel -relocation-model=static < %s | FileCheck --check-prefixes=ALL,SYM32,O32,O32LE %s
|
||||
|
||||
; RUN-TODO: llc -march=mips64 -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
|
||||
; RUN-TODO: llc -march=mips64el -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
|
||||
|
||||
; RUN: llc -march=mips64 -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,NEW %s
|
||||
; RUN: llc -march=mips64el -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,NEW %s
|
||||
|
||||
; RUN: llc -march=mips64 -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,SYM64,NEW %s
|
||||
; RUN: llc -march=mips64el -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,SYM64,NEW %s
|
||||
|
||||
; Test the floating point arguments for all ABI's and byte orders as specified
|
||||
; by section 5 of MD00305 (MIPS ABIs Described).
|
||||
;
|
||||
; N32/N64 are identical in this area so their checks have been combined into
|
||||
; the 'NEW' prefix (the N stands for New).
|
||||
|
||||
@bytes = global [11 x i8] zeroinitializer
|
||||
@dwords = global [11 x i64] zeroinitializer
|
||||
@floats = global [11 x float] zeroinitializer
|
||||
@doubles = global [11 x double] zeroinitializer
|
||||
|
||||
define void @double_args(double %a, double %b, double %c, double %d, double %e,
|
||||
double %f, double %g, double %h, double %i) nounwind {
|
||||
entry:
|
||||
%0 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 1
|
||||
store volatile double %a, double* %0
|
||||
%1 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 2
|
||||
store volatile double %b, double* %1
|
||||
%2 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 3
|
||||
store volatile double %c, double* %2
|
||||
%3 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 4
|
||||
store volatile double %d, double* %3
|
||||
%4 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 5
|
||||
store volatile double %e, double* %4
|
||||
%5 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 6
|
||||
store volatile double %f, double* %5
|
||||
%6 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 7
|
||||
store volatile double %g, double* %6
|
||||
%7 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 8
|
||||
store volatile double %h, double* %7
|
||||
%8 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 9
|
||||
store volatile double %i, double* %8
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: double_args:
|
||||
; We won't test the way the global address is calculated in this test. This is
|
||||
; just to get the register number for the other checks.
|
||||
; SYM32-DAG: addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(doubles)
|
||||
; SYM64-DAG: daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(doubles)
|
||||
|
||||
; The first argument is floating point so floating point registers are used.
|
||||
; The first argument is the same for O32/N32/N64 but the second argument differs
|
||||
; by register
|
||||
; ALL-DAG: sdc1 $f12, 8([[R2]])
|
||||
; O32-DAG: sdc1 $f14, 16([[R2]])
|
||||
; NEW-DAG: sdc1 $f13, 16([[R2]])
|
||||
|
||||
; O32 has run out of argument registers and starts using the stack
|
||||
; O32-DAG: ldc1 [[F1:\$f[0-9]+]], 16($sp)
|
||||
; O32-DAG: sdc1 [[F1]], 24([[R2]])
|
||||
; NEW-DAG: sdc1 $f14, 24([[R2]])
|
||||
; O32-DAG: ldc1 [[F1:\$f[0-9]+]], 24($sp)
|
||||
; O32-DAG: sdc1 [[F1]], 32([[R2]])
|
||||
; NEW-DAG: sdc1 $f15, 32([[R2]])
|
||||
; O32-DAG: ldc1 [[F1:\$f[0-9]+]], 32($sp)
|
||||
; O32-DAG: sdc1 [[F1]], 40([[R2]])
|
||||
; NEW-DAG: sdc1 $f16, 40([[R2]])
|
||||
; O32-DAG: ldc1 [[F1:\$f[0-9]+]], 40($sp)
|
||||
; O32-DAG: sdc1 [[F1]], 48([[R2]])
|
||||
; NEW-DAG: sdc1 $f17, 48([[R2]])
|
||||
; O32-DAG: ldc1 [[F1:\$f[0-9]+]], 48($sp)
|
||||
; O32-DAG: sdc1 [[F1]], 56([[R2]])
|
||||
; NEW-DAG: sdc1 $f18, 56([[R2]])
|
||||
; O32-DAG: ldc1 [[F1:\$f[0-9]+]], 56($sp)
|
||||
; O32-DAG: sdc1 [[F1]], 64([[R2]])
|
||||
; NEW-DAG: sdc1 $f19, 64([[R2]])
|
||||
|
||||
; N32/N64 have run out of registers and start using the stack too
|
||||
; O32-DAG: ldc1 [[F1:\$f[0-9]+]], 64($sp)
|
||||
; O32-DAG: sdc1 [[F1]], 72([[R2]])
|
||||
; NEW-DAG: ldc1 [[F1:\$f[0-9]+]], 0($sp)
|
||||
; NEW-DAG: sdc1 [[F1]], 72([[R2]])
|
||||
|
||||
define void @float_args(float %a, float %b, float %c, float %d, float %e,
|
||||
float %f, float %g, float %h, float %i) nounwind {
|
||||
entry:
|
||||
%0 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 1
|
||||
store volatile float %a, float* %0
|
||||
%1 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 2
|
||||
store volatile float %b, float* %1
|
||||
%2 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 3
|
||||
store volatile float %c, float* %2
|
||||
%3 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 4
|
||||
store volatile float %d, float* %3
|
||||
%4 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 5
|
||||
store volatile float %e, float* %4
|
||||
%5 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 6
|
||||
store volatile float %f, float* %5
|
||||
%6 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 7
|
||||
store volatile float %g, float* %6
|
||||
%7 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 8
|
||||
store volatile float %h, float* %7
|
||||
%8 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 9
|
||||
store volatile float %i, float* %8
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: float_args:
|
||||
; We won't test the way the global address is calculated in this test. This is
|
||||
; just to get the register number for the other checks.
|
||||
; SYM32-DAG: addiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(floats)
|
||||
; SYM64-DAG: daddiu [[R1:\$[0-9]]], ${{[0-9]+}}, %lo(floats)
|
||||
|
||||
; The first argument is floating point so floating point registers are used.
|
||||
; The first argument is the same for O32/N32/N64 but the second argument differs
|
||||
; by register
|
||||
; ALL-DAG: swc1 $f12, 4([[R1]])
|
||||
; O32-DAG: swc1 $f14, 8([[R1]])
|
||||
; NEW-DAG: swc1 $f13, 8([[R1]])
|
||||
|
||||
; O32 has run out of argument registers and (in theory) starts using the stack
|
||||
; I've yet to find a reference in the documentation about this but GCC uses up
|
||||
; the remaining two argument slots in the GPR's first. We'll do the same for
|
||||
; compatibility.
|
||||
; O32-DAG: sw $6, 12([[R1]])
|
||||
; NEW-DAG: swc1 $f14, 12([[R1]])
|
||||
; O32-DAG: sw $7, 16([[R1]])
|
||||
; NEW-DAG: swc1 $f15, 16([[R1]])
|
||||
|
||||
; O32 is definitely out of registers now and switches to the stack.
|
||||
; O32-DAG: lwc1 [[F1:\$f[0-9]+]], 16($sp)
|
||||
; O32-DAG: swc1 [[F1]], 20([[R1]])
|
||||
; NEW-DAG: swc1 $f16, 20([[R1]])
|
||||
; O32-DAG: lwc1 [[F1:\$f[0-9]+]], 20($sp)
|
||||
; O32-DAG: swc1 [[F1]], 24([[R1]])
|
||||
; NEW-DAG: swc1 $f17, 24([[R1]])
|
||||
; O32-DAG: lwc1 [[F1:\$f[0-9]+]], 24($sp)
|
||||
; O32-DAG: swc1 [[F1]], 28([[R1]])
|
||||
; NEW-DAG: swc1 $f18, 28([[R1]])
|
||||
; O32-DAG: lwc1 [[F1:\$f[0-9]+]], 28($sp)
|
||||
; O32-DAG: swc1 [[F1]], 32([[R1]])
|
||||
; NEW-DAG: swc1 $f19, 32([[R1]])
|
||||
|
||||
; N32/N64 have run out of registers and start using the stack too
|
||||
; O32-DAG: lwc1 [[F1:\$f[0-9]+]], 32($sp)
|
||||
; O32-DAG: swc1 [[F1]], 36([[R1]])
|
||||
; NEW-DAG: lwc1 [[F1:\$f[0-9]+]], 0($sp)
|
||||
; NEW-DAG: swc1 [[F1]], 36([[R1]])
|
||||
|
||||
|
||||
define void @double_arg2(i8 %a, double %b) nounwind {
|
||||
entry:
|
||||
%0 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 1
|
||||
store volatile i8 %a, i8* %0
|
||||
%1 = getelementptr [11 x double], [11 x double]* @doubles, i32 0, i32 1
|
||||
store volatile double %b, double* %1
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: double_arg2:
|
||||
; We won't test the way the global address is calculated in this test. This is
|
||||
; just to get the register number for the other checks.
|
||||
; SYM32-DAG: addiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
|
||||
; SYM64-DAG: daddiu [[R1:\$[0-9]]], ${{[0-9]+}}, %lo(bytes)
|
||||
; SYM32-DAG: addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(doubles)
|
||||
; SYM64-DAG: daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(doubles)
|
||||
|
||||
; The first argument is the same in O32/N32/N64.
|
||||
; ALL-DAG: sb $4, 1([[R1]])
|
||||
|
||||
; The first argument isn't floating point so floating point registers are not
|
||||
; used in O32, but N32/N64 will still use them.
|
||||
; The second slot is insufficiently aligned for double on O32 so it is skipped.
|
||||
; Also, double occupies two slots on O32 and only one for N32/N64.
|
||||
; O32LE-DAG: mtc1 $6, [[F1:\$f[0-9]*[02468]+]]
|
||||
; O32LE-DAG: mtc1 $7, [[F2:\$f[0-9]*[13579]+]]
|
||||
; O32BE-DAG: mtc1 $6, [[F2:\$f[0-9]*[13579]+]]
|
||||
; O32BE-DAG: mtc1 $7, [[F1:\$f[0-9]*[02468]+]]
|
||||
; O32-DAG: sdc1 [[F1]], 8([[R2]])
|
||||
; NEW-DAG: sdc1 $f13, 8([[R2]])
|
||||
|
||||
define void @float_arg2(i8 %a, float %b) nounwind {
|
||||
entry:
|
||||
%0 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 1
|
||||
store volatile i8 %a, i8* %0
|
||||
%1 = getelementptr [11 x float], [11 x float]* @floats, i32 0, i32 1
|
||||
store volatile float %b, float* %1
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: float_arg2:
|
||||
; We won't test the way the global address is calculated in this test. This is
|
||||
; just to get the register number for the other checks.
|
||||
; SYM32-DAG: addiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
|
||||
; SYM64-DAG: daddiu [[R1:\$[0-9]]], ${{[0-9]+}}, %lo(bytes)
|
||||
; SYM32-DAG: addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(floats)
|
||||
; SYM64-DAG: daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(floats)
|
||||
|
||||
; The first argument is the same in O32/N32/N64.
|
||||
; ALL-DAG: sb $4, 1([[R1]])
|
||||
|
||||
; The first argument isn't floating point so floating point registers are not
|
||||
; used in O32, but N32/N64 will still use them.
|
||||
; MD00305 and GCC disagree on this one. MD00305 says that floats are treated
|
||||
; as 8-byte aligned and occupy two slots on O32. GCC is treating them as 4-byte
|
||||
; aligned and occupying one slot. We'll use GCC's definition.
|
||||
; O32-DAG: sw $5, 4([[R2]])
|
||||
; NEW-DAG: swc1 $f13, 4([[R2]])
|
@ -1,49 +0,0 @@
|
||||
; RUN: llc -march=mips64 -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32 %s
|
||||
; RUN: llc -march=mips64el -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32 %s
|
||||
|
||||
; RUN: llc -march=mips64 -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,SYM64 %s
|
||||
; RUN: llc -march=mips64el -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,SYM64 %s
|
||||
|
||||
; Test the fp128 arguments for all ABI's and byte orders as specified
|
||||
; by section 2 of the MIPSpro N32 Handbook.
|
||||
;
|
||||
; O32 is not tested because long double is the same as double on O32.
|
||||
|
||||
@ldoubles = global [11 x fp128] zeroinitializer
|
||||
|
||||
define void @ldouble_args(fp128 %a, fp128 %b, fp128 %c, fp128 %d, fp128 %e) nounwind {
|
||||
entry:
|
||||
%0 = getelementptr [11 x fp128], [11 x fp128]* @ldoubles, i32 0, i32 1
|
||||
store volatile fp128 %a, fp128* %0
|
||||
%1 = getelementptr [11 x fp128], [11 x fp128]* @ldoubles, i32 0, i32 2
|
||||
store volatile fp128 %b, fp128* %1
|
||||
%2 = getelementptr [11 x fp128], [11 x fp128]* @ldoubles, i32 0, i32 3
|
||||
store volatile fp128 %c, fp128* %2
|
||||
%3 = getelementptr [11 x fp128], [11 x fp128]* @ldoubles, i32 0, i32 4
|
||||
store volatile fp128 %d, fp128* %3
|
||||
%4 = getelementptr [11 x fp128], [11 x fp128]* @ldoubles, i32 0, i32 5
|
||||
store volatile fp128 %e, fp128* %4
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: ldouble_args:
|
||||
; We won't test the way the global address is calculated in this test. This is
|
||||
; just to get the register number for the other checks.
|
||||
; SYM32-DAG: addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(ldoubles)
|
||||
; SYM64-DAG: daddiu [[R2:\$[0-9]]], ${{[0-9]+}}, %lo(ldoubles)
|
||||
|
||||
; The first four arguments are the same in N32/N64.
|
||||
; ALL-DAG: sdc1 $f12, 16([[R2]])
|
||||
; ALL-DAG: sdc1 $f13, 24([[R2]])
|
||||
; ALL-DAG: sdc1 $f14, 32([[R2]])
|
||||
; ALL-DAG: sdc1 $f15, 40([[R2]])
|
||||
; ALL-DAG: sdc1 $f16, 48([[R2]])
|
||||
; ALL-DAG: sdc1 $f17, 56([[R2]])
|
||||
; ALL-DAG: sdc1 $f18, 64([[R2]])
|
||||
; ALL-DAG: sdc1 $f19, 72([[R2]])
|
||||
|
||||
; N32/N64 have run out of registers and starts using the stack too
|
||||
; ALL-DAG: ld [[R3:\$[0-9]+]], 0($sp)
|
||||
; ALL-DAG: ld [[R4:\$[0-9]+]], 8($sp)
|
||||
; ALL-DAG: sd [[R3]], 80([[R2]])
|
||||
; ALL-DAG: sd [[R4]], 88([[R2]])
|
@ -1,80 +0,0 @@
|
||||
; RUN: llc < %s -march=mips64 -target-abi n64 -mcpu=mips64r2 | FileCheck %s -check-prefixes=ALL,MIPSEB
|
||||
; RUN: llc < %s -march=mips64el -target-abi n64 -mcpu=mips64r2 | FileCheck %s -check-prefixes=ALL,MIPSEL
|
||||
; RUN: llc < %s -march=mips64 -target-abi n32 -mcpu=mips64r2 | FileCheck %s -check-prefixes=ALL,MIPSEB
|
||||
; RUN: llc < %s -march=mips64el -target-abi n32 -mcpu=mips64r2 | FileCheck %s -check-prefixes=ALL,MIPSEL
|
||||
|
||||
; #include <stdio.h>
|
||||
;
|
||||
; struct S1 {
|
||||
; char x1;
|
||||
; short x2;
|
||||
; char x3;
|
||||
; };
|
||||
;
|
||||
; struct S2 {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; char x4;
|
||||
; char x5;
|
||||
; };
|
||||
;
|
||||
; void fS1(struct S1 s);
|
||||
; void fS2(struct S2 s);
|
||||
;
|
||||
; void f1() {
|
||||
; struct S1 s1_1;
|
||||
; fS1(s1_1);
|
||||
; }
|
||||
;
|
||||
; void f2() {
|
||||
; struct S2 s2_1;
|
||||
; fS2(s2_1);
|
||||
; }
|
||||
;
|
||||
; int main() {
|
||||
; f1();
|
||||
; f2();
|
||||
; }
|
||||
|
||||
%struct.S1 = type { i8, i16, i8 }
|
||||
%struct.S2 = type { i8, i8, i8, i8, i8 }
|
||||
|
||||
declare void @fS1(i48 inreg) #1
|
||||
declare void @fS2(i40 inreg) #1
|
||||
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #2
|
||||
|
||||
define void @f1() #0 {
|
||||
entry:
|
||||
%s1_1 = alloca %struct.S1, align 2
|
||||
%s1_1.coerce = alloca { i48 }
|
||||
%0 = bitcast { i48 }* %s1_1.coerce to i8*
|
||||
%1 = bitcast %struct.S1* %s1_1 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 6, i32 0, i1 false)
|
||||
%2 = getelementptr { i48 }, { i48 }* %s1_1.coerce, i32 0, i32 0
|
||||
%3 = load i48, i48* %2, align 1
|
||||
call void @fS1(i48 inreg %3)
|
||||
ret void
|
||||
; ALL-LABEL: f1:
|
||||
|
||||
; MIPSEB: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 16
|
||||
; MIPSEL-NOT: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 16
|
||||
}
|
||||
|
||||
define void @f2() #0 {
|
||||
entry:
|
||||
%s2_1 = alloca %struct.S2, align 1
|
||||
%s2_1.coerce = alloca { i40 }
|
||||
%0 = bitcast { i40 }* %s2_1.coerce to i8*
|
||||
%1 = bitcast %struct.S2* %s2_1 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 5, i32 0, i1 false)
|
||||
%2 = getelementptr { i40 }, { i40 }* %s2_1.coerce, i32 0, i32 0
|
||||
%3 = load i40, i40* %2, align 1
|
||||
call void @fS2(i40 inreg %3)
|
||||
ret void
|
||||
; ALL-LABEL: f2:
|
||||
|
||||
; MIPSEB: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 24
|
||||
; MIPSEL-NOT: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 24
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
; RUN: llc -mtriple=mips-unknown-linux-gnu -relocation-model=static < %s | FileCheck --check-prefixes=ALL,SYM32,O32-BE %s
|
||||
; RUN: llc -mtriple=mipsel-unknown-linux-gnu -relocation-model=static < %s | FileCheck --check-prefixes=ALL,SYM32,O32-LE %s
|
||||
|
||||
; RUN-TODO: llc -mtriple=mips64-unknown-linux-gnu -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32-BE %s
|
||||
; RUN-TODO: llc -mtriple=mips64el-unknown-linux-gnu -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32-LE %s
|
||||
|
||||
; RUN: llc -mtriple=mips64-unknown-linux-gnu -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,NEW-BE %s
|
||||
; RUN: llc -mtriple=mips64el-unknown-linux-gnu -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,NEW-LE %s
|
||||
|
||||
; RUN: llc -mtriple=mips64-unknown-linux-gnu -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,SYM64,NEW-BE %s
|
||||
; RUN: llc -mtriple=mips64el-unknown-linux-gnu -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,SYM64,NEW-LE %s
|
||||
|
||||
; Test small structures for all ABI's and byte orders.
|
||||
;
|
||||
; N32/N64 are identical in this area so their checks have been combined into
|
||||
; the 'NEW' prefix (the N stands for New).
|
||||
|
||||
@bytes = global [2 x i8] zeroinitializer
|
||||
|
||||
define void @s_i8(i8 inreg %a) nounwind {
|
||||
entry:
|
||||
store i8 %a, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @bytes, i32 0, i32 1)
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: s_i8:
|
||||
|
||||
; SYM32-DAG: lui [[PTR_HI:\$[0-9]+]], %hi(bytes)
|
||||
; SYM32-DAG: addiu [[PTR:\$[0-9]+]], [[PTR_HI]], %lo(bytes)
|
||||
|
||||
; SYM64-DAG: addiu [[PTR:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
|
||||
|
||||
; O32-BE-DAG: srl [[ARG:\$[0-9]+]], $4, 24
|
||||
; O32-BE-DAG: sb [[ARG]], 1([[PTR]])
|
||||
|
||||
; O32-LE-DAG: sb $4, 1([[PTR]])
|
||||
|
||||
; NEW-BE-DAG: dsrl [[ARG:\$[0-9]+]], $4, 56
|
||||
; NEW-BE-DAG: sb [[ARG]], 1([[PTR]])
|
||||
|
||||
; NEW-LE-DAG: sb $4, 1([[PTR]])
|
@ -1,284 +0,0 @@
|
||||
; RUN: llc --march=mips64 -mcpu=mips64r2 < %s | FileCheck %s
|
||||
|
||||
; Generated from the C program:
|
||||
;
|
||||
; #include <stdio.h>
|
||||
; #include <string.h>
|
||||
;
|
||||
; struct SmallStruct_1b {
|
||||
; char x1;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_2b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_3b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_4b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; char x4;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_5b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; char x4;
|
||||
; char x5;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_6b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; char x4;
|
||||
; char x5;
|
||||
; char x6;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_7b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; char x4;
|
||||
; char x5;
|
||||
; char x6;
|
||||
; char x7;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_8b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; char x4;
|
||||
; char x5;
|
||||
; char x6;
|
||||
; char x7;
|
||||
; char x8;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_9b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; char x4;
|
||||
; char x5;
|
||||
; char x6;
|
||||
; char x7;
|
||||
; char x8;
|
||||
; char x9;
|
||||
; };
|
||||
;
|
||||
; void varArgF_SmallStruct(char* c, ...);
|
||||
;
|
||||
; void smallStruct_1b(struct SmallStruct_1b* ss) {
|
||||
; varArgF_SmallStruct("", *ss);
|
||||
; }
|
||||
;
|
||||
; void smallStruct_2b(struct SmallStruct_2b* ss) {
|
||||
; varArgF_SmallStruct("", *ss);
|
||||
; }
|
||||
;
|
||||
; void smallStruct_3b(struct SmallStruct_3b* ss)
|
||||
; {
|
||||
; varArgF_SmallStruct("", *ss);
|
||||
; }
|
||||
;
|
||||
; void smallStruct_4b(struct SmallStruct_4b* ss)
|
||||
; {
|
||||
; varArgF_SmallStruct("", *ss);
|
||||
; }
|
||||
;
|
||||
; void smallStruct_5b(struct SmallStruct_5b* ss)
|
||||
; {
|
||||
; varArgF_SmallStruct("", *ss);
|
||||
; }
|
||||
;
|
||||
; void smallStruct_6b(struct SmallStruct_6b* ss)
|
||||
; {
|
||||
; varArgF_SmallStruct("", *ss);
|
||||
; }
|
||||
;
|
||||
; void smallStruct_7b(struct SmallStruct_7b* ss)
|
||||
; {
|
||||
; varArgF_SmallStruct("", *ss);
|
||||
; }
|
||||
;
|
||||
; void smallStruct_8b(struct SmallStruct_8b* ss)
|
||||
; {
|
||||
; varArgF_SmallStruct("", *ss);
|
||||
; }
|
||||
;
|
||||
; void smallStruct_9b(struct SmallStruct_9b* ss)
|
||||
; {
|
||||
; varArgF_SmallStruct("", *ss);
|
||||
; }
|
||||
|
||||
%struct.SmallStruct_1b = type { i8 }
|
||||
%struct.SmallStruct_2b = type { i8, i8 }
|
||||
%struct.SmallStruct_3b = type { i8, i8, i8 }
|
||||
%struct.SmallStruct_4b = type { i8, i8, i8, i8 }
|
||||
%struct.SmallStruct_5b = type { i8, i8, i8, i8, i8 }
|
||||
%struct.SmallStruct_6b = type { i8, i8, i8, i8, i8, i8 }
|
||||
%struct.SmallStruct_7b = type { i8, i8, i8, i8, i8, i8, i8 }
|
||||
%struct.SmallStruct_8b = type { i8, i8, i8, i8, i8, i8, i8, i8 }
|
||||
%struct.SmallStruct_9b = type { i8, i8, i8, i8, i8, i8, i8, i8, i8 }
|
||||
|
||||
@.str = private unnamed_addr constant [3 x i8] c"01\00", align 1
|
||||
|
||||
declare void @varArgF_SmallStruct(i8* %c, ...)
|
||||
|
||||
define void @smallStruct_1b(%struct.SmallStruct_1b* %ss) #0 {
|
||||
entry:
|
||||
%ss.addr = alloca %struct.SmallStruct_1b*, align 8
|
||||
store %struct.SmallStruct_1b* %ss, %struct.SmallStruct_1b** %ss.addr, align 8
|
||||
%0 = load %struct.SmallStruct_1b*, %struct.SmallStruct_1b** %ss.addr, align 8
|
||||
%1 = bitcast %struct.SmallStruct_1b* %0 to { i8 }*
|
||||
%2 = getelementptr { i8 }, { i8 }* %1, i32 0, i32 0
|
||||
%3 = load i8, i8* %2, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i8 inreg %3)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_1b:
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 56
|
||||
}
|
||||
|
||||
define void @smallStruct_2b(%struct.SmallStruct_2b* %ss) #0 {
|
||||
entry:
|
||||
%ss.addr = alloca %struct.SmallStruct_2b*, align 8
|
||||
store %struct.SmallStruct_2b* %ss, %struct.SmallStruct_2b** %ss.addr, align 8
|
||||
%0 = load %struct.SmallStruct_2b*, %struct.SmallStruct_2b** %ss.addr, align 8
|
||||
%1 = bitcast %struct.SmallStruct_2b* %0 to { i16 }*
|
||||
%2 = getelementptr { i16 }, { i16 }* %1, i32 0, i32 0
|
||||
%3 = load i16, i16* %2, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i16 inreg %3)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_2b:
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 48
|
||||
}
|
||||
|
||||
define void @smallStruct_3b(%struct.SmallStruct_3b* %ss) #0 {
|
||||
entry:
|
||||
%ss.addr = alloca %struct.SmallStruct_3b*, align 8
|
||||
%.coerce = alloca { i24 }
|
||||
store %struct.SmallStruct_3b* %ss, %struct.SmallStruct_3b** %ss.addr, align 8
|
||||
%0 = load %struct.SmallStruct_3b*, %struct.SmallStruct_3b** %ss.addr, align 8
|
||||
%1 = bitcast { i24 }* %.coerce to i8*
|
||||
%2 = bitcast %struct.SmallStruct_3b* %0 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 3, i32 0, i1 false)
|
||||
%3 = getelementptr { i24 }, { i24 }* %.coerce, i32 0, i32 0
|
||||
%4 = load i24, i24* %3, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i24 inreg %4)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_3b:
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 40
|
||||
}
|
||||
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #1
|
||||
|
||||
define void @smallStruct_4b(%struct.SmallStruct_4b* %ss) #0 {
|
||||
entry:
|
||||
%ss.addr = alloca %struct.SmallStruct_4b*, align 8
|
||||
store %struct.SmallStruct_4b* %ss, %struct.SmallStruct_4b** %ss.addr, align 8
|
||||
%0 = load %struct.SmallStruct_4b*, %struct.SmallStruct_4b** %ss.addr, align 8
|
||||
%1 = bitcast %struct.SmallStruct_4b* %0 to { i32 }*
|
||||
%2 = getelementptr { i32 }, { i32 }* %1, i32 0, i32 0
|
||||
%3 = load i32, i32* %2, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i32 inreg %3)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_4b:
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 32
|
||||
}
|
||||
|
||||
define void @smallStruct_5b(%struct.SmallStruct_5b* %ss) #0 {
|
||||
entry:
|
||||
%ss.addr = alloca %struct.SmallStruct_5b*, align 8
|
||||
%.coerce = alloca { i40 }
|
||||
store %struct.SmallStruct_5b* %ss, %struct.SmallStruct_5b** %ss.addr, align 8
|
||||
%0 = load %struct.SmallStruct_5b*, %struct.SmallStruct_5b** %ss.addr, align 8
|
||||
%1 = bitcast { i40 }* %.coerce to i8*
|
||||
%2 = bitcast %struct.SmallStruct_5b* %0 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 5, i32 0, i1 false)
|
||||
%3 = getelementptr { i40 }, { i40 }* %.coerce, i32 0, i32 0
|
||||
%4 = load i40, i40* %3, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i40 inreg %4)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_5b:
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 24
|
||||
}
|
||||
|
||||
define void @smallStruct_6b(%struct.SmallStruct_6b* %ss) #0 {
|
||||
entry:
|
||||
%ss.addr = alloca %struct.SmallStruct_6b*, align 8
|
||||
%.coerce = alloca { i48 }
|
||||
store %struct.SmallStruct_6b* %ss, %struct.SmallStruct_6b** %ss.addr, align 8
|
||||
%0 = load %struct.SmallStruct_6b*, %struct.SmallStruct_6b** %ss.addr, align 8
|
||||
%1 = bitcast { i48 }* %.coerce to i8*
|
||||
%2 = bitcast %struct.SmallStruct_6b* %0 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 6, i32 0, i1 false)
|
||||
%3 = getelementptr { i48 }, { i48 }* %.coerce, i32 0, i32 0
|
||||
%4 = load i48, i48* %3, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i48 inreg %4)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_6b:
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 16
|
||||
}
|
||||
|
||||
define void @smallStruct_7b(%struct.SmallStruct_7b* %ss) #0 {
|
||||
entry:
|
||||
%ss.addr = alloca %struct.SmallStruct_7b*, align 8
|
||||
%.coerce = alloca { i56 }
|
||||
store %struct.SmallStruct_7b* %ss, %struct.SmallStruct_7b** %ss.addr, align 8
|
||||
%0 = load %struct.SmallStruct_7b*, %struct.SmallStruct_7b** %ss.addr, align 8
|
||||
%1 = bitcast { i56 }* %.coerce to i8*
|
||||
%2 = bitcast %struct.SmallStruct_7b* %0 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 7, i32 0, i1 false)
|
||||
%3 = getelementptr { i56 }, { i56 }* %.coerce, i32 0, i32 0
|
||||
%4 = load i56, i56* %3, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i56 inreg %4)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_7b:
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 8
|
||||
}
|
||||
|
||||
define void @smallStruct_8b(%struct.SmallStruct_8b* %ss) #0 {
|
||||
entry:
|
||||
%ss.addr = alloca %struct.SmallStruct_8b*, align 8
|
||||
store %struct.SmallStruct_8b* %ss, %struct.SmallStruct_8b** %ss.addr, align 8
|
||||
%0 = load %struct.SmallStruct_8b*, %struct.SmallStruct_8b** %ss.addr, align 8
|
||||
%1 = bitcast %struct.SmallStruct_8b* %0 to { i64 }*
|
||||
%2 = getelementptr { i64 }, { i64 }* %1, i32 0, i32 0
|
||||
%3 = load i64, i64* %2, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i64 inreg %3)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_8b:
|
||||
; Check that the structure is not shifted before the pointer to str is loaded.
|
||||
; CHECK-NOT: dsll
|
||||
; CHECK: lui
|
||||
}
|
||||
|
||||
define void @smallStruct_9b(%struct.SmallStruct_9b* %ss) #0 {
|
||||
entry:
|
||||
%ss.addr = alloca %struct.SmallStruct_9b*, align 8
|
||||
%.coerce = alloca { i64, i8 }
|
||||
store %struct.SmallStruct_9b* %ss, %struct.SmallStruct_9b** %ss.addr, align 8
|
||||
%0 = load %struct.SmallStruct_9b*, %struct.SmallStruct_9b** %ss.addr, align 8
|
||||
%1 = bitcast { i64, i8 }* %.coerce to i8*
|
||||
%2 = bitcast %struct.SmallStruct_9b* %0 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 9, i32 0, i1 false)
|
||||
%3 = getelementptr { i64, i8 }, { i64, i8 }* %.coerce, i32 0, i32 0
|
||||
%4 = load i64, i64* %3, align 1
|
||||
%5 = getelementptr { i64, i8 }, { i64, i8 }* %.coerce, i32 0, i32 1
|
||||
%6 = load i8, i8* %5, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i64 inreg %4, i8 inreg %6)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_9b:
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 56
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
; RUN: llc --march=mips64 -mcpu=mips64r2 < %s | FileCheck %s
|
||||
|
||||
; Generated from the C program:
|
||||
;
|
||||
; #include <stdio.h>
|
||||
; #include <string.h>
|
||||
;
|
||||
; struct SmallStruct_1b1s {
|
||||
; char x1;
|
||||
; short x2;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_1b1i {
|
||||
; char x1;
|
||||
; int x2;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_1b1s1b {
|
||||
; char x1;
|
||||
; short x2;
|
||||
; char x3;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_1s1i {
|
||||
; short x1;
|
||||
; int x2;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_3b1s {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; short x4;
|
||||
; };
|
||||
;
|
||||
; void varArgF_SmallStruct(char* c, ...);
|
||||
;
|
||||
; void smallStruct_1b1s(struct SmallStruct_1b1s* ss)
|
||||
; {
|
||||
; varArgF_SmallStruct("", *ss);
|
||||
; }
|
||||
;
|
||||
; void smallStruct_1b1i(struct SmallStruct_1b1i* ss)
|
||||
; {
|
||||
; varArgF_SmallStruct("", *ss);
|
||||
; }
|
||||
;
|
||||
; void smallStruct_1b1s1b(struct SmallStruct_1b1s1b* ss)
|
||||
; {
|
||||
; varArgF_SmallStruct("", *ss);
|
||||
; }
|
||||
;
|
||||
; void smallStruct_1s1i(struct SmallStruct_1s1i* ss)
|
||||
; {
|
||||
; varArgF_SmallStruct("", *ss);
|
||||
; }
|
||||
;
|
||||
; void smallStruct_3b1s(struct SmallStruct_3b1s* ss)
|
||||
; {
|
||||
; varArgF_SmallStruct("", *ss);
|
||||
; }
|
||||
|
||||
%struct.SmallStruct_1b1s = type { i8, i16 }
|
||||
%struct.SmallStruct_1b1i = type { i8, i32 }
|
||||
%struct.SmallStruct_1b1s1b = type { i8, i16, i8 }
|
||||
%struct.SmallStruct_1s1i = type { i16, i32 }
|
||||
%struct.SmallStruct_3b1s = type { i8, i8, i8, i16 }
|
||||
|
||||
@.str = private unnamed_addr constant [3 x i8] c"01\00", align 1
|
||||
|
||||
declare void @varArgF_SmallStruct(i8* %c, ...)
|
||||
|
||||
define void @smallStruct_1b1s(%struct.SmallStruct_1b1s* %ss) #0 {
|
||||
entry:
|
||||
%ss.addr = alloca %struct.SmallStruct_1b1s*, align 8
|
||||
store %struct.SmallStruct_1b1s* %ss, %struct.SmallStruct_1b1s** %ss.addr, align 8
|
||||
%0 = load %struct.SmallStruct_1b1s*, %struct.SmallStruct_1b1s** %ss.addr, align 8
|
||||
%1 = bitcast %struct.SmallStruct_1b1s* %0 to { i32 }*
|
||||
%2 = getelementptr { i32 }, { i32 }* %1, i32 0, i32 0
|
||||
%3 = load i32, i32* %2, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i32 inreg %3)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_1b1s:
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 32
|
||||
}
|
||||
|
||||
define void @smallStruct_1b1i(%struct.SmallStruct_1b1i* %ss) #0 {
|
||||
entry:
|
||||
%ss.addr = alloca %struct.SmallStruct_1b1i*, align 8
|
||||
store %struct.SmallStruct_1b1i* %ss, %struct.SmallStruct_1b1i** %ss.addr, align 8
|
||||
%0 = load %struct.SmallStruct_1b1i*, %struct.SmallStruct_1b1i** %ss.addr, align 8
|
||||
%1 = bitcast %struct.SmallStruct_1b1i* %0 to { i64 }*
|
||||
%2 = getelementptr { i64 }, { i64 }* %1, i32 0, i32 0
|
||||
%3 = load i64, i64* %2, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i64 inreg %3)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_1b1i:
|
||||
; CHECK-NOT: dsll
|
||||
; CHECK: lui
|
||||
}
|
||||
|
||||
define void @smallStruct_1b1s1b(%struct.SmallStruct_1b1s1b* %ss) #0 {
|
||||
entry:
|
||||
%ss.addr = alloca %struct.SmallStruct_1b1s1b*, align 8
|
||||
%.coerce = alloca { i48 }
|
||||
store %struct.SmallStruct_1b1s1b* %ss, %struct.SmallStruct_1b1s1b** %ss.addr, align 8
|
||||
%0 = load %struct.SmallStruct_1b1s1b*, %struct.SmallStruct_1b1s1b** %ss.addr, align 8
|
||||
%1 = bitcast { i48 }* %.coerce to i8*
|
||||
%2 = bitcast %struct.SmallStruct_1b1s1b* %0 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 6, i32 0, i1 false)
|
||||
%3 = getelementptr { i48 }, { i48 }* %.coerce, i32 0, i32 0
|
||||
%4 = load i48, i48* %3, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i48 inreg %4)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_1b1s1b:
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 16
|
||||
}
|
||||
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #1
|
||||
|
||||
define void @smallStruct_1s1i(%struct.SmallStruct_1s1i* %ss) #0 {
|
||||
entry:
|
||||
%ss.addr = alloca %struct.SmallStruct_1s1i*, align 8
|
||||
store %struct.SmallStruct_1s1i* %ss, %struct.SmallStruct_1s1i** %ss.addr, align 8
|
||||
%0 = load %struct.SmallStruct_1s1i*, %struct.SmallStruct_1s1i** %ss.addr, align 8
|
||||
%1 = bitcast %struct.SmallStruct_1s1i* %0 to { i64 }*
|
||||
%2 = getelementptr { i64 }, { i64 }* %1, i32 0, i32 0
|
||||
%3 = load i64, i64* %2, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i64 inreg %3)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_1s1i:
|
||||
; CHECK-NOT: dsll
|
||||
; CHECK: lui
|
||||
}
|
||||
|
||||
define void @smallStruct_3b1s(%struct.SmallStruct_3b1s* %ss) #0 {
|
||||
entry:
|
||||
%ss.addr = alloca %struct.SmallStruct_3b1s*, align 8
|
||||
%.coerce = alloca { i48 }
|
||||
store %struct.SmallStruct_3b1s* %ss, %struct.SmallStruct_3b1s** %ss.addr, align 8
|
||||
%0 = load %struct.SmallStruct_3b1s*, %struct.SmallStruct_3b1s** %ss.addr, align 8
|
||||
%1 = bitcast { i48 }* %.coerce to i8*
|
||||
%2 = bitcast %struct.SmallStruct_3b1s* %0 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 6, i32 0, i1 false)
|
||||
%3 = getelementptr { i48 }, { i48 }* %.coerce, i32 0, i32 0
|
||||
%4 = load i48, i48* %3, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i48 inreg %4)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_3b1s:
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 16
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
; RUN: llc --march=mips64 -mcpu=mips64r2 < %s | FileCheck %s
|
||||
|
||||
; Generated from the C program:
|
||||
;
|
||||
; #include <stdio.h>
|
||||
; #include <string.h>
|
||||
;
|
||||
; struct SmallStruct_1b {
|
||||
; char x1;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_2b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_3b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_4b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; char x4;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_5b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; char x4;
|
||||
; char x5;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_6b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; char x4;
|
||||
; char x5;
|
||||
; char x6;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_7b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; char x4;
|
||||
; char x5;
|
||||
; char x6;
|
||||
; char x7;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_8b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; char x4;
|
||||
; char x5;
|
||||
; char x6;
|
||||
; char x7;
|
||||
; char x8;
|
||||
; };
|
||||
;
|
||||
; struct SmallStruct_9b {
|
||||
; char x1;
|
||||
; char x2;
|
||||
; char x3;
|
||||
; char x4;
|
||||
; char x5;
|
||||
; char x6;
|
||||
; char x7;
|
||||
; char x8;
|
||||
; char x9;
|
||||
; };
|
||||
;
|
||||
; void varArgF_SmallStruct(char* c, ...);
|
||||
;
|
||||
; void smallStruct_1b_x9(struct SmallStruct_1b* ss1, struct SmallStruct_1b* ss2, struct SmallStruct_1b* ss3, struct SmallStruct_1b* ss4, struct SmallStruct_1b* ss5, struct SmallStruct_1b* ss6, struct SmallStruct_1b* ss7, struct SmallStruct_1b* ss8, struct SmallStruct_1b* ss9)
|
||||
; {
|
||||
; varArgF_SmallStruct("", *ss1, *ss2, *ss3, *ss4, *ss5, *ss6, *ss7, *ss8, *ss9);
|
||||
; }
|
||||
|
||||
%struct.SmallStruct_1b = type { i8 }
|
||||
|
||||
@.str = private unnamed_addr constant [3 x i8] c"01\00", align 1
|
||||
|
||||
declare void @varArgF_SmallStruct(i8* %c, ...)
|
||||
|
||||
define void @smallStruct_1b_x9(%struct.SmallStruct_1b* %ss1, %struct.SmallStruct_1b* %ss2, %struct.SmallStruct_1b* %ss3, %struct.SmallStruct_1b* %ss4, %struct.SmallStruct_1b* %ss5, %struct.SmallStruct_1b* %ss6, %struct.SmallStruct_1b* %ss7, %struct.SmallStruct_1b* %ss8, %struct.SmallStruct_1b* %ss9) #0 {
|
||||
entry:
|
||||
%ss1.addr = alloca %struct.SmallStruct_1b*, align 8
|
||||
%ss2.addr = alloca %struct.SmallStruct_1b*, align 8
|
||||
%ss3.addr = alloca %struct.SmallStruct_1b*, align 8
|
||||
%ss4.addr = alloca %struct.SmallStruct_1b*, align 8
|
||||
%ss5.addr = alloca %struct.SmallStruct_1b*, align 8
|
||||
%ss6.addr = alloca %struct.SmallStruct_1b*, align 8
|
||||
%ss7.addr = alloca %struct.SmallStruct_1b*, align 8
|
||||
%ss8.addr = alloca %struct.SmallStruct_1b*, align 8
|
||||
%ss9.addr = alloca %struct.SmallStruct_1b*, align 8
|
||||
store %struct.SmallStruct_1b* %ss1, %struct.SmallStruct_1b** %ss1.addr, align 8
|
||||
store %struct.SmallStruct_1b* %ss2, %struct.SmallStruct_1b** %ss2.addr, align 8
|
||||
store %struct.SmallStruct_1b* %ss3, %struct.SmallStruct_1b** %ss3.addr, align 8
|
||||
store %struct.SmallStruct_1b* %ss4, %struct.SmallStruct_1b** %ss4.addr, align 8
|
||||
store %struct.SmallStruct_1b* %ss5, %struct.SmallStruct_1b** %ss5.addr, align 8
|
||||
store %struct.SmallStruct_1b* %ss6, %struct.SmallStruct_1b** %ss6.addr, align 8
|
||||
store %struct.SmallStruct_1b* %ss7, %struct.SmallStruct_1b** %ss7.addr, align 8
|
||||
store %struct.SmallStruct_1b* %ss8, %struct.SmallStruct_1b** %ss8.addr, align 8
|
||||
store %struct.SmallStruct_1b* %ss9, %struct.SmallStruct_1b** %ss9.addr, align 8
|
||||
%0 = load %struct.SmallStruct_1b*, %struct.SmallStruct_1b** %ss1.addr, align 8
|
||||
%1 = load %struct.SmallStruct_1b*, %struct.SmallStruct_1b** %ss2.addr, align 8
|
||||
%2 = load %struct.SmallStruct_1b*, %struct.SmallStruct_1b** %ss3.addr, align 8
|
||||
%3 = load %struct.SmallStruct_1b*, %struct.SmallStruct_1b** %ss4.addr, align 8
|
||||
%4 = load %struct.SmallStruct_1b*, %struct.SmallStruct_1b** %ss5.addr, align 8
|
||||
%5 = load %struct.SmallStruct_1b*, %struct.SmallStruct_1b** %ss6.addr, align 8
|
||||
%6 = load %struct.SmallStruct_1b*, %struct.SmallStruct_1b** %ss7.addr, align 8
|
||||
%7 = load %struct.SmallStruct_1b*, %struct.SmallStruct_1b** %ss8.addr, align 8
|
||||
%8 = load %struct.SmallStruct_1b*, %struct.SmallStruct_1b** %ss9.addr, align 8
|
||||
%9 = bitcast %struct.SmallStruct_1b* %0 to { i8 }*
|
||||
%10 = getelementptr { i8 }, { i8 }* %9, i32 0, i32 0
|
||||
%11 = load i8, i8* %10, align 1
|
||||
%12 = bitcast %struct.SmallStruct_1b* %1 to { i8 }*
|
||||
%13 = getelementptr { i8 }, { i8 }* %12, i32 0, i32 0
|
||||
%14 = load i8, i8* %13, align 1
|
||||
%15 = bitcast %struct.SmallStruct_1b* %2 to { i8 }*
|
||||
%16 = getelementptr { i8 }, { i8 }* %15, i32 0, i32 0
|
||||
%17 = load i8, i8* %16, align 1
|
||||
%18 = bitcast %struct.SmallStruct_1b* %3 to { i8 }*
|
||||
%19 = getelementptr { i8 }, { i8 }* %18, i32 0, i32 0
|
||||
%20 = load i8, i8* %19, align 1
|
||||
%21 = bitcast %struct.SmallStruct_1b* %4 to { i8 }*
|
||||
%22 = getelementptr { i8 }, { i8 }* %21, i32 0, i32 0
|
||||
%23 = load i8, i8* %22, align 1
|
||||
%24 = bitcast %struct.SmallStruct_1b* %5 to { i8 }*
|
||||
%25 = getelementptr { i8 }, { i8 }* %24, i32 0, i32 0
|
||||
%26 = load i8, i8* %25, align 1
|
||||
%27 = bitcast %struct.SmallStruct_1b* %6 to { i8 }*
|
||||
%28 = getelementptr { i8 }, { i8 }* %27, i32 0, i32 0
|
||||
%29 = load i8, i8* %28, align 1
|
||||
%30 = bitcast %struct.SmallStruct_1b* %7 to { i8 }*
|
||||
%31 = getelementptr { i8 }, { i8 }* %30, i32 0, i32 0
|
||||
%32 = load i8, i8* %31, align 1
|
||||
%33 = bitcast %struct.SmallStruct_1b* %8 to { i8 }*
|
||||
%34 = getelementptr { i8 }, { i8 }* %33, i32 0, i32 0
|
||||
%35 = load i8, i8* %34, align 1
|
||||
call void (i8*, ...) @varArgF_SmallStruct(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i8 inreg %11, i8 inreg %14, i8 inreg %17, i8 inreg %20, i8 inreg %23, i8 inreg %26, i8 inreg %29, i8 inreg %32, i8 inreg %35)
|
||||
ret void
|
||||
; CHECK-LABEL: smallStruct_1b_x9:
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 56
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 56
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 56
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 56
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 56
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 56
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 56
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 56
|
||||
; CHECK: dsll $[[R1:[0-9]+]], $[[R2:[0-9]+]], 56
|
||||
}
|
File diff suppressed because it is too large
Load Diff
172
external/llvm/test/CodeGen/Mips/cconv/arguments.ll
vendored
172
external/llvm/test/CodeGen/Mips/cconv/arguments.ll
vendored
@ -1,172 +0,0 @@
|
||||
; RUN: llc -march=mips -relocation-model=static < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
|
||||
; RUN: llc -march=mipsel -relocation-model=static < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
|
||||
|
||||
; RUN-TODO: llc -march=mips64 -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
|
||||
; RUN-TODO: llc -march=mips64el -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,O32 %s
|
||||
|
||||
; RUN: llc -march=mips64 -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,NEW %s
|
||||
; RUN: llc -march=mips64el -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,SYM32,NEW %s
|
||||
|
||||
; RUN: llc -march=mips64 -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,SYM64,NEW %s
|
||||
; RUN: llc -march=mips64el -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,SYM64,NEW %s
|
||||
|
||||
; Test the integer arguments for all ABI's and byte orders as specified by
|
||||
; section 5 of MD00305 (MIPS ABIs Described).
|
||||
;
|
||||
; N32/N64 are identical in this area so their checks have been combined into
|
||||
; the 'NEW' prefix (the N stands for New).
|
||||
;
|
||||
; Varargs are covered in arguments-hard-float-varargs.ll.
|
||||
|
||||
@bytes = global [11 x i8] zeroinitializer
|
||||
@dwords = global [11 x i64] zeroinitializer
|
||||
@floats = global [11 x float] zeroinitializer
|
||||
@doubles = global [11 x double] zeroinitializer
|
||||
|
||||
define void @align_to_arg_slots(i8 signext %a, i8 signext %b, i8 signext %c,
|
||||
i8 signext %d, i8 signext %e, i8 signext %f,
|
||||
i8 signext %g, i8 signext %h, i8 signext %i,
|
||||
i8 signext %j) nounwind {
|
||||
entry:
|
||||
%0 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 1
|
||||
store volatile i8 %a, i8* %0
|
||||
%1 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 2
|
||||
store volatile i8 %b, i8* %1
|
||||
%2 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 3
|
||||
store volatile i8 %c, i8* %2
|
||||
%3 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 4
|
||||
store volatile i8 %d, i8* %3
|
||||
%4 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 5
|
||||
store volatile i8 %e, i8* %4
|
||||
%5 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 6
|
||||
store volatile i8 %f, i8* %5
|
||||
%6 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 7
|
||||
store volatile i8 %g, i8* %6
|
||||
%7 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 8
|
||||
store volatile i8 %h, i8* %7
|
||||
%8 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 9
|
||||
store volatile i8 %i, i8* %8
|
||||
%9 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 10
|
||||
store volatile i8 %j, i8* %9
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: align_to_arg_slots:
|
||||
; We won't test the way the global address is calculated in this test. This is
|
||||
; just to get the register number for the other checks.
|
||||
; SYM32-DAG: addiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
|
||||
; SYM64-DAG: daddiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
|
||||
|
||||
; The first four arguments are the same in O32/N32/N64
|
||||
; ALL-DAG: sb $4, 1([[R1]])
|
||||
; ALL-DAG: sb $5, 2([[R1]])
|
||||
; ALL-DAG: sb $6, 3([[R1]])
|
||||
; ALL-DAG: sb $7, 4([[R1]])
|
||||
|
||||
; N32/N64 get an extra four arguments in registers
|
||||
; O32 starts loading from the stack. The addresses start at 16 because space is
|
||||
; always reserved for the first four arguments.
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 16($sp)
|
||||
; O32-DAG: sb [[R3]], 5([[R1]])
|
||||
; NEW-DAG: sb $8, 5([[R1]])
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 20($sp)
|
||||
; O32-DAG: sb [[R3]], 6([[R1]])
|
||||
; NEW-DAG: sb $9, 6([[R1]])
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 24($sp)
|
||||
; O32-DAG: sb [[R3]], 7([[R1]])
|
||||
; NEW-DAG: sb $10, 7([[R1]])
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 28($sp)
|
||||
; O32-DAG: sb [[R3]], 8([[R1]])
|
||||
; NEW-DAG: sb $11, 8([[R1]])
|
||||
|
||||
; O32/N32/N64 are accessing the stack at this point.
|
||||
; Unlike O32, N32/N64 do not reserve space for the arguments.
|
||||
; increase by 4 for O32 and 8 for N32/N64.
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 32($sp)
|
||||
; O32-DAG: sb [[R3]], 9([[R1]])
|
||||
; NEW-DAG: ld [[R3:\$[0-9]+]], 0($sp)
|
||||
; NEW-DAG: sb [[R3]], 9([[R1]])
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 36($sp)
|
||||
; O32-DAG: sb [[R3]], 10([[R1]])
|
||||
; NEW-DAG: ld [[R3:\$[0-9]+]], 8($sp)
|
||||
; NEW-DAG: sb [[R3]], 10([[R1]])
|
||||
|
||||
define void @slot_skipping(i8 signext %a, i64 signext %b, i8 signext %c,
|
||||
i8 signext %d, i8 signext %e, i8 signext %f,
|
||||
i8 signext %g, i64 signext %i, i8 signext %j) nounwind {
|
||||
entry:
|
||||
%0 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 1
|
||||
store volatile i8 %a, i8* %0
|
||||
%1 = getelementptr [11 x i64], [11 x i64]* @dwords, i32 0, i32 1
|
||||
store volatile i64 %b, i64* %1
|
||||
%2 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 2
|
||||
store volatile i8 %c, i8* %2
|
||||
%3 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 3
|
||||
store volatile i8 %d, i8* %3
|
||||
%4 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 4
|
||||
store volatile i8 %e, i8* %4
|
||||
%5 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 5
|
||||
store volatile i8 %f, i8* %5
|
||||
%6 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 6
|
||||
store volatile i8 %g, i8* %6
|
||||
%7 = getelementptr [11 x i64], [11 x i64]* @dwords, i32 0, i32 2
|
||||
store volatile i64 %i, i64* %7
|
||||
%8 = getelementptr [11 x i8], [11 x i8]* @bytes, i32 0, i32 7
|
||||
store volatile i8 %j, i8* %8
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: slot_skipping:
|
||||
; We won't test the way the global address is calculated in this test. This is
|
||||
; just to get the register number for the other checks.
|
||||
; SYM32-DAG: addiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
|
||||
; SYM64-DAG: daddiu [[R1:\$[0-9]+]], ${{[0-9]+}}, %lo(bytes)
|
||||
; SYM32-DAG: addiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
|
||||
; SYM64-DAG: daddiu [[R2:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
|
||||
|
||||
; The first argument is the same in O32/N32/N64.
|
||||
; ALL-DAG: sb $4, 1([[R1]])
|
||||
|
||||
; The second slot is insufficiently aligned for i64 on O32 so it is skipped.
|
||||
; Also, i64 occupies two slots on O32 and only one for N32/N64.
|
||||
; O32-DAG: sw $6, 8([[R2]])
|
||||
; O32-DAG: sw $7, 12([[R2]])
|
||||
; NEW-DAG: sd $5, 8([[R2]])
|
||||
|
||||
; N32/N64 get an extra four arguments in registers and still have two left from
|
||||
; the first four.
|
||||
; O32 starts loading from the stack. The addresses start at 16 because space is
|
||||
; always reserved for the first four arguments.
|
||||
; It's not clear why O32 uses lbu for this argument, but it's not wrong so we'll
|
||||
; accept it for now. The only IR difference is that this argument has
|
||||
; anyext from i8 and align 8 on it.
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 16($sp)
|
||||
; O32-DAG: sb [[R3]], 2([[R1]])
|
||||
; NEW-DAG: sb $6, 2([[R1]])
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 20($sp)
|
||||
; O32-DAG: sb [[R3]], 3([[R1]])
|
||||
; NEW-DAG: sb $7, 3([[R1]])
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 24($sp)
|
||||
; O32-DAG: sb [[R3]], 4([[R1]])
|
||||
; NEW-DAG: sb $8, 4([[R1]])
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 28($sp)
|
||||
; O32-DAG: sb [[R3]], 5([[R1]])
|
||||
; NEW-DAG: sb $9, 5([[R1]])
|
||||
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 32($sp)
|
||||
; O32-DAG: sb [[R3]], 6([[R1]])
|
||||
; NEW-DAG: sb $10, 6([[R1]])
|
||||
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 40($sp)
|
||||
; O32-DAG: sw [[R3]], 16([[R2]])
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 44($sp)
|
||||
; O32-DAG: sw [[R3]], 20([[R2]])
|
||||
; NEW-DAG: sd $11, 16([[R2]])
|
||||
|
||||
; O32/N32/N64 are accessing the stack at this point.
|
||||
; Unlike O32, N32/N64 do not reserve space for the arguments.
|
||||
; increase by 4 for O32 and 8 for N32/N64.
|
||||
; O32-DAG: lw [[R3:\$[0-9]+]], 48($sp)
|
||||
; O32-DAG: sb [[R3]], 7([[R1]])
|
||||
; NEW-DAG: ld [[R3:\$[0-9]+]], 0($sp)
|
||||
; NEW-DAG: sb [[R3]], 7([[R1]])
|
@ -1,116 +0,0 @@
|
||||
; RUN: llc -march=mips < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
; RUN: llc -march=mipsel < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
; RUN: llc -march=mips < %s | FileCheck --check-prefixes=ALL,O32-INV %s
|
||||
; RUN: llc -march=mipsel < %s | FileCheck --check-prefixes=ALL,O32-INV %s
|
||||
|
||||
; RUN-TODO: llc -march=mips64 -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
; RUN-TODO: llc -march=mips64el -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
; RUN-TODO: llc -march=mips64 -target-abi o32 < %s | FileCheck --check-prefixes=ALL,ALL-INV,O32-INV %s
|
||||
; RUN-TODO: llc -march=mips64el -target-abi o32 < %s | FileCheck --check-prefixes=ALL,ALL-INV,O32-INV %s
|
||||
|
||||
; RUN: llc -march=mips64 -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
|
||||
; RUN: llc -march=mips64el -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
|
||||
; RUN: llc -march=mips64 -target-abi n32 < %s | FileCheck --check-prefixes=ALL,ALL-INV,N32-INV %s
|
||||
; RUN: llc -march=mips64el -target-abi n32 < %s | FileCheck --check-prefixes=ALL,ALL-INV,N32-INV %s
|
||||
|
||||
; RUN: llc -march=mips64 -target-abi n64 < %s | FileCheck --check-prefixes=ALL,N64 %s
|
||||
; RUN: llc -march=mips64el -target-abi n64 < %s | FileCheck --check-prefixes=ALL,N64 %s
|
||||
; RUN: llc -march=mips64 -target-abi n64 < %s | FileCheck --check-prefixes=ALL,ALL-INV,N64-INV %s
|
||||
; RUN: llc -march=mips64el -target-abi n64 < %s | FileCheck --check-prefixes=ALL,ALL-INV,N64-INV %s
|
||||
|
||||
; RUN: llc -march=mips -mcpu=mips32r6 -mattr=micromips -filetype=obj < %s -o - | llvm-objdump -no-show-raw-insn -arch mips -mcpu=mips32r6 -mattr=micromips -d - | FileCheck --check-prefix=MM32R6 %s
|
||||
|
||||
; Test the the callee-saved registers are callee-saved as specified by section
|
||||
; 2 of the MIPSpro N32 Handbook and section 3 of the SYSV ABI spec.
|
||||
|
||||
define void @fpu_clobber() nounwind {
|
||||
entry:
|
||||
call void asm "# Clobber", "~{$f0},~{$f1},~{$f2},~{$f3},~{$f4},~{$f5},~{$f6},~{$f7},~{$f8},~{$f9},~{$f10},~{$f11},~{$f12},~{$f13},~{$f14},~{$f15},~{$f16},~{$f17},~{$f18},~{$f19},~{$f20},~{$f21},~{$f22},~{$f23},~{$f24},~{$f25},~{$f26},~{$f27},~{$f28},~{$f29},~{$f30},~{$f31}"()
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: fpu_clobber:
|
||||
; ALL-INV-NOT: sdc1 $f0,
|
||||
; ALL-INV-NOT: sdc1 $f1,
|
||||
; ALL-INV-NOT: sdc1 $f2,
|
||||
; ALL-INV-NOT: sdc1 $f3,
|
||||
; ALL-INV-NOT: sdc1 $f4,
|
||||
; ALL-INV-NOT: sdc1 $f5,
|
||||
; ALL-INV-NOT: sdc1 $f6,
|
||||
; ALL-INV-NOT: sdc1 $f7,
|
||||
; ALL-INV-NOT: sdc1 $f8,
|
||||
; ALL-INV-NOT: sdc1 $f9,
|
||||
; ALL-INV-NOT: sdc1 $f10,
|
||||
; ALL-INV-NOT: sdc1 $f11,
|
||||
; ALL-INV-NOT: sdc1 $f12,
|
||||
; ALL-INV-NOT: sdc1 $f13,
|
||||
; ALL-INV-NOT: sdc1 $f14,
|
||||
; ALL-INV-NOT: sdc1 $f15,
|
||||
; ALL-INV-NOT: sdc1 $f16,
|
||||
; ALL-INV-NOT: sdc1 $f17,
|
||||
; ALL-INV-NOT: sdc1 $f18,
|
||||
; ALL-INV-NOT: sdc1 $f19,
|
||||
; ALL-INV-NOT: sdc1 $f21,
|
||||
; ALL-INV-NOT: sdc1 $f23,
|
||||
|
||||
; O32: addiu $sp, $sp, -48
|
||||
; O32-DAG: sdc1 [[F20:\$f20]], [[OFF20:[0-9]+]]($sp)
|
||||
; O32-DAG: sdc1 [[F22:\$f22]], [[OFF22:[0-9]+]]($sp)
|
||||
; O32-DAG: sdc1 [[F24:\$f24]], [[OFF24:[0-9]+]]($sp)
|
||||
; O32-DAG: sdc1 [[F26:\$f26]], [[OFF26:[0-9]+]]($sp)
|
||||
; O32-DAG: sdc1 [[F28:\$f28]], [[OFF28:[0-9]+]]($sp)
|
||||
; O32-DAG: sdc1 [[F30:\$f30]], [[OFF30:[0-9]+]]($sp)
|
||||
; O32-DAG: ldc1 [[F20]], [[OFF20]]($sp)
|
||||
; O32-DAG: ldc1 [[F22]], [[OFF22]]($sp)
|
||||
; O32-DAG: ldc1 [[F24]], [[OFF24]]($sp)
|
||||
; O32-INV-NOT: sdc1 $f25,
|
||||
; O32-DAG: ldc1 [[F26]], [[OFF26]]($sp)
|
||||
; O32-INV-NOT: sdc1 $f27,
|
||||
; O32-DAG: ldc1 [[F28]], [[OFF28]]($sp)
|
||||
; O32-INV-NOT: sdc1 $f29,
|
||||
; O32-DAG: ldc1 [[F30]], [[OFF30]]($sp)
|
||||
; O32-INV-NOT: sdc1 $f31,
|
||||
; O32: addiu $sp, $sp, 48
|
||||
|
||||
; N32: addiu $sp, $sp, -48
|
||||
; N32-DAG: sdc1 [[F20:\$f20]], [[OFF20:[0-9]+]]($sp)
|
||||
; N32-DAG: sdc1 [[F22:\$f22]], [[OFF22:[0-9]+]]($sp)
|
||||
; N32-DAG: sdc1 [[F24:\$f24]], [[OFF24:[0-9]+]]($sp)
|
||||
; N32-DAG: sdc1 [[F26:\$f26]], [[OFF26:[0-9]+]]($sp)
|
||||
; N32-DAG: sdc1 [[F28:\$f28]], [[OFF28:[0-9]+]]($sp)
|
||||
; N32-DAG: sdc1 [[F30:\$f30]], [[OFF30:[0-9]+]]($sp)
|
||||
; N32-DAG: ldc1 [[F20]], [[OFF20]]($sp)
|
||||
; N32-DAG: ldc1 [[F22]], [[OFF22]]($sp)
|
||||
; N32-DAG: ldc1 [[F24]], [[OFF24]]($sp)
|
||||
; N32-INV-NOT: sdc1 $f25,
|
||||
; N32-DAG: ldc1 [[F26]], [[OFF26]]($sp)
|
||||
; N32-INV-NOT: sdc1 $f27,
|
||||
; N32-DAG: ldc1 [[F28]], [[OFF28]]($sp)
|
||||
; N32-INV-NOT: sdc1 $f29,
|
||||
; N32-DAG: ldc1 [[F30]], [[OFF30]]($sp)
|
||||
; N32-INV-NOT: sdc1 $f31,
|
||||
; N32: addiu $sp, $sp, 48
|
||||
|
||||
; N64: addiu $sp, $sp, -64
|
||||
; N64-INV-NOT: sdc1 $f20,
|
||||
; N64-INV-NOT: sdc1 $f22,
|
||||
; N64-DAG: sdc1 [[F24:\$f24]], [[OFF24:[0-9]+]]($sp)
|
||||
; N64-DAG: sdc1 [[F25:\$f25]], [[OFF25:[0-9]+]]($sp)
|
||||
; N64-DAG: sdc1 [[F26:\$f26]], [[OFF26:[0-9]+]]($sp)
|
||||
; N64-DAG: sdc1 [[F27:\$f27]], [[OFF27:[0-9]+]]($sp)
|
||||
; N64-DAG: sdc1 [[F28:\$f28]], [[OFF28:[0-9]+]]($sp)
|
||||
; N64-DAG: sdc1 [[F29:\$f29]], [[OFF29:[0-9]+]]($sp)
|
||||
; N64-DAG: sdc1 [[F30:\$f30]], [[OFF30:[0-9]+]]($sp)
|
||||
; N64-DAG: sdc1 [[F31:\$f31]], [[OFF31:[0-9]+]]($sp)
|
||||
; N64-DAG: ldc1 [[F24]], [[OFF24]]($sp)
|
||||
; N64-DAG: ldc1 [[F25]], [[OFF25]]($sp)
|
||||
; N64-DAG: ldc1 [[F26]], [[OFF26]]($sp)
|
||||
; N64-DAG: ldc1 [[F27]], [[OFF27]]($sp)
|
||||
; N64-DAG: ldc1 [[F28]], [[OFF28]]($sp)
|
||||
; N64-DAG: ldc1 [[F29]], [[OFF29]]($sp)
|
||||
; N64-DAG: ldc1 [[F30]], [[OFF30]]($sp)
|
||||
; N64-DAG: ldc1 [[F31]], [[OFF31]]($sp)
|
||||
; N64: addiu $sp, $sp, 64
|
||||
|
||||
; Check the mapping between LDC164 and LDC1_64_MMR6.
|
||||
; MM32R6: ldc1
|
@ -1,58 +0,0 @@
|
||||
; RUN: llc -march=mips -mattr=+o32,+fpxx < %s | FileCheck --check-prefixes=ALL,O32-FPXX %s
|
||||
; RUN: llc -march=mipsel -mattr=+o32,+fpxx < %s | FileCheck --check-prefixes=ALL,O32-FPXX %s
|
||||
; RUN: llc -march=mips -mattr=+o32,+fpxx < %s | FileCheck --check-prefixes=ALL,O32-FPXX-INV %s
|
||||
; RUN: llc -march=mipsel -mattr=+o32,+fpxx < %s | FileCheck --check-prefixes=ALL,O32-FPXX-INV %s
|
||||
|
||||
; RUN-TODO: llc -march=mips64 -mattr=+o32,+fpxx < %s | FileCheck --check-prefixes=ALL,O32-FPXX %s
|
||||
; RUN-TODO: llc -march=mips64el -mattr=+o32,+fpxx < %s | FileCheck --check-prefixes=ALL,O32-FPXX %s
|
||||
; RUN-TODO: llc -march=mips64 -mattr=+o32,+fpxx < %s | FileCheck --check-prefixes=ALL,O32-FPXX-INV,O32-FPXX-INV %s
|
||||
; RUN-TODO: llc -march=mips64el -mattr=+o32,+fpxx < %s | FileCheck --check-prefixes=ALL,O32-FPXX-INV,O32-FPXX-INV %s
|
||||
|
||||
define void @fpu_clobber() nounwind {
|
||||
entry:
|
||||
call void asm "# Clobber", "~{$f0},~{$f1},~{$f2},~{$f3},~{$f4},~{$f5},~{$f6},~{$f7},~{$f8},~{$f9},~{$f10},~{$f11},~{$f12},~{$f13},~{$f14},~{$f15},~{$f16},~{$f17},~{$f18},~{$f19},~{$f20},~{$f21},~{$f22},~{$f23},~{$f24},~{$f25},~{$f26},~{$f27},~{$f28},~{$f29},~{$f30},~{$f31}"()
|
||||
ret void
|
||||
}
|
||||
|
||||
; O32-FPXX-LABEL: fpu_clobber:
|
||||
; O32-FPXX-INV-NOT: sdc1 $f0,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f1,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f2,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f3,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f4,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f5,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f6,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f7,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f8,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f9,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f10,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f11,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f12,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f13,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f14,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f15,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f16,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f17,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f18,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f19,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f21,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f23,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f25,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f27,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f29,
|
||||
; O32-FPXX-INV-NOT: sdc1 $f31,
|
||||
|
||||
; O32-FPXX: addiu $sp, $sp, -48
|
||||
; O32-FPXX-DAG: sdc1 [[F20:\$f20]], [[OFF20:[0-9]+]]($sp)
|
||||
; O32-FPXX-DAG: sdc1 [[F22:\$f22]], [[OFF22:[0-9]+]]($sp)
|
||||
; O32-FPXX-DAG: sdc1 [[F24:\$f24]], [[OFF24:[0-9]+]]($sp)
|
||||
; O32-FPXX-DAG: sdc1 [[F26:\$f26]], [[OFF26:[0-9]+]]($sp)
|
||||
; O32-FPXX-DAG: sdc1 [[F28:\$f28]], [[OFF28:[0-9]+]]($sp)
|
||||
; O32-FPXX-DAG: sdc1 [[F30:\$f30]], [[OFF30:[0-9]+]]($sp)
|
||||
; O32-FPXX-DAG: ldc1 [[F20]], [[OFF20]]($sp)
|
||||
; O32-FPXX-DAG: ldc1 [[F22]], [[OFF22]]($sp)
|
||||
; O32-FPXX-DAG: ldc1 [[F24]], [[OFF24]]($sp)
|
||||
; O32-FPXX-DAG: ldc1 [[F26]], [[OFF26]]($sp)
|
||||
; O32-FPXX-DAG: ldc1 [[F28]], [[OFF28]]($sp)
|
||||
; O32-FPXX-DAG: ldc1 [[F30]], [[OFF30]]($sp)
|
||||
; O32-FPXX: addiu $sp, $sp, 48
|
@ -1,24 +0,0 @@
|
||||
; RUN: llc -march=mips -mattr=+o32,+fp64 < %s | FileCheck --check-prefix=O32-FP64-INV %s
|
||||
; RUN: llc -march=mipsel -mattr=+o32,+fp64 < %s | FileCheck --check-prefix=O32-FP64-INV %s
|
||||
|
||||
; RUN: llc -march=mips -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=O32-FPXX %s
|
||||
; RUN: llc -march=mipsel -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=O32-FPXX %s
|
||||
|
||||
; RUN-TODO: llc -march=mips64 -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=O32-FPXX %s
|
||||
; RUN-TODO: llc -march=mips64el -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=O32-FPXX %s
|
||||
|
||||
define void @fpu_clobber() nounwind {
|
||||
entry:
|
||||
call void asm "# Clobber", "~{$f21}"()
|
||||
ret void
|
||||
}
|
||||
|
||||
; O32-FPXX-LABEL: fpu_clobber:
|
||||
|
||||
; O32-FPXX: addiu $sp, $sp, -8
|
||||
|
||||
; O32-FP64-INV-NOT: sdc1 $f20,
|
||||
; O32-FPXX-DAG: sdc1 [[F20:\$f20]], [[OFF20:[0-9]+]]($sp)
|
||||
; O32-FPXX-DAG: ldc1 [[F20]], [[OFF20]]($sp)
|
||||
|
||||
; O32-FPXX: addiu $sp, $sp, 8
|
@ -1,167 +0,0 @@
|
||||
; RUN: llc -march=mips < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
; RUN: llc -march=mipsel < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
; RUN: llc -march=mips < %s | FileCheck --check-prefixes=ALL,O32-INV %s
|
||||
; RUN: llc -march=mipsel < %s | FileCheck --check-prefixes=ALL,O32-INV %s
|
||||
|
||||
; RUN-TODO: llc -march=mips64 -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
; RUN-TODO: llc -march=mips64el -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
; RUN-TODO: llc -march=mips64 -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32-INV %s
|
||||
; RUN-TODO: llc -march=mips64el -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32-INV %s
|
||||
|
||||
; RUN: llc -march=mips64 -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
|
||||
; RUN: llc -march=mips64el -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
|
||||
; RUN: llc -march=mips64 -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32-INV %s
|
||||
; RUN: llc -march=mips64el -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32-INV %s
|
||||
|
||||
; RUN: llc -march=mips64 -target-abi n64 < %s | FileCheck --check-prefixes=ALL,N64 %s
|
||||
; RUN: llc -march=mips64el -target-abi n64 < %s | FileCheck --check-prefixes=ALL,N64 %s
|
||||
; RUN: llc -march=mips64 -target-abi n64 < %s | FileCheck --check-prefixes=ALL,N64-INV %s
|
||||
; RUN: llc -march=mips64el -target-abi n64 < %s | FileCheck --check-prefixes=ALL,N64-INV %s
|
||||
|
||||
; Test the callee-saved registers are callee-saved as specified by section
|
||||
; 2 of the MIPSpro N32 Handbook and section 3 of the SYSV ABI spec.
|
||||
|
||||
define void @gpr_clobber() nounwind {
|
||||
entry:
|
||||
; Clobbering the stack pointer is a bad idea so we'll skip that one
|
||||
call void asm "# Clobber", "~{$0},~{$1},~{$2},~{$3},~{$4},~{$5},~{$6},~{$7},~{$8},~{$9},~{$10},~{$11},~{$12},~{$13},~{$14},~{$15},~{$16},~{$17},~{$18},~{$19},~{$20},~{$21},~{$22},~{$23},~{$24},~{$25},~{$26},~{$27},~{$28},~{$30},~{$31}"()
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: gpr_clobber:
|
||||
; O32: addiu $sp, $sp, -40
|
||||
; O32-INV-NOT: sw $0,
|
||||
; O32-INV-NOT: sw $1,
|
||||
; O32-INV-NOT: sw $2,
|
||||
; O32-INV-NOT: sw $3,
|
||||
; O32-INV-NOT: sw $4,
|
||||
; O32-INV-NOT: sw $5,
|
||||
; O32-INV-NOT: sw $6,
|
||||
; O32-INV-NOT: sw $7,
|
||||
; O32-INV-NOT: sw $8,
|
||||
; O32-INV-NOT: sw $9,
|
||||
; O32-INV-NOT: sw $10,
|
||||
; O32-INV-NOT: sw $11,
|
||||
; O32-INV-NOT: sw $12,
|
||||
; O32-INV-NOT: sw $13,
|
||||
; O32-INV-NOT: sw $14,
|
||||
; O32-INV-NOT: sw $15,
|
||||
; O32-DAG: sw [[G16:\$16]], [[OFF16:[0-9]+]]($sp)
|
||||
; O32-DAG: sw [[G17:\$17]], [[OFF17:[0-9]+]]($sp)
|
||||
; O32-DAG: sw [[G18:\$18]], [[OFF18:[0-9]+]]($sp)
|
||||
; O32-DAG: sw [[G19:\$19]], [[OFF19:[0-9]+]]($sp)
|
||||
; O32-DAG: sw [[G20:\$20]], [[OFF20:[0-9]+]]($sp)
|
||||
; O32-DAG: sw [[G21:\$21]], [[OFF21:[0-9]+]]($sp)
|
||||
; O32-DAG: sw [[G22:\$22]], [[OFF22:[0-9]+]]($sp)
|
||||
; O32-DAG: sw [[G23:\$23]], [[OFF23:[0-9]+]]($sp)
|
||||
; O32-INV-NOT: sw $24,
|
||||
; O32-INV-NOT: sw $25,
|
||||
; O32-INV-NOT: sw $26,
|
||||
; O32-INV-NOT: sw $27,
|
||||
; O32-INV-NOT: sw $28,
|
||||
; O32-INV-NOT: sw $29,
|
||||
; O32-DAG: sw [[G30:\$fp]], [[OFF30:[0-9]+]]($sp)
|
||||
; O32-DAG: sw [[G31:\$fp]], [[OFF31:[0-9]+]]($sp)
|
||||
; O32-DAG: lw [[G16]], [[OFF16]]($sp)
|
||||
; O32-DAG: lw [[G17]], [[OFF17]]($sp)
|
||||
; O32-DAG: lw [[G18]], [[OFF18]]($sp)
|
||||
; O32-DAG: lw [[G19]], [[OFF19]]($sp)
|
||||
; O32-DAG: lw [[G20]], [[OFF20]]($sp)
|
||||
; O32-DAG: lw [[G21]], [[OFF21]]($sp)
|
||||
; O32-DAG: lw [[G22]], [[OFF22]]($sp)
|
||||
; O32-DAG: lw [[G23]], [[OFF23]]($sp)
|
||||
; O32-DAG: lw [[G30]], [[OFF30]]($sp)
|
||||
; O32-DAG: lw [[G31]], [[OFF31]]($sp)
|
||||
; O32: addiu $sp, $sp, 40
|
||||
|
||||
; N32: addiu $sp, $sp, -96
|
||||
; N32-INV-NOT: sd $0,
|
||||
; N32-INV-NOT: sd $1,
|
||||
; N32-INV-NOT: sd $2,
|
||||
; N32-INV-NOT: sd $3,
|
||||
; N32-INV-NOT: sd $4,
|
||||
; N32-INV-NOT: sd $5,
|
||||
; N32-INV-NOT: sd $6,
|
||||
; N32-INV-NOT: sd $7,
|
||||
; N32-INV-NOT: sd $8,
|
||||
; N32-INV-NOT: sd $9,
|
||||
; N32-INV-NOT: sd $10,
|
||||
; N32-INV-NOT: sd $11,
|
||||
; N32-INV-NOT: sd $12,
|
||||
; N32-INV-NOT: sd $13,
|
||||
; N32-INV-NOT: sd $14,
|
||||
; N32-INV-NOT: sd $15,
|
||||
; N32-DAG: sd [[G16:\$16]], [[OFF16:[0-9]+]]($sp)
|
||||
; N32-DAG: sd [[G17:\$17]], [[OFF17:[0-9]+]]($sp)
|
||||
; N32-DAG: sd [[G18:\$18]], [[OFF18:[0-9]+]]($sp)
|
||||
; N32-DAG: sd [[G19:\$19]], [[OFF19:[0-9]+]]($sp)
|
||||
; N32-DAG: sd [[G20:\$20]], [[OFF20:[0-9]+]]($sp)
|
||||
; N32-DAG: sd [[G21:\$21]], [[OFF21:[0-9]+]]($sp)
|
||||
; N32-DAG: sd [[G22:\$22]], [[OFF22:[0-9]+]]($sp)
|
||||
; N32-DAG: sd [[G23:\$23]], [[OFF23:[0-9]+]]($sp)
|
||||
; N32-INV-NOT: sd $24,
|
||||
; N32-INV-NOT: sd $25,
|
||||
; N32-INV-NOT: sd $26,
|
||||
; N32-INV-NOT: sd $27,
|
||||
; N32-DAG: sd [[G28:\$gp]], [[OFF28:[0-9]+]]($sp)
|
||||
; N32-INV-NOT: sd $29,
|
||||
; N32-DAG: sd [[G30:\$fp]], [[OFF30:[0-9]+]]($sp)
|
||||
; N32-DAG: sd [[G31:\$fp]], [[OFF31:[0-9]+]]($sp)
|
||||
; N32-DAG: ld [[G16]], [[OFF16]]($sp)
|
||||
; N32-DAG: ld [[G17]], [[OFF17]]($sp)
|
||||
; N32-DAG: ld [[G18]], [[OFF18]]($sp)
|
||||
; N32-DAG: ld [[G19]], [[OFF19]]($sp)
|
||||
; N32-DAG: ld [[G20]], [[OFF20]]($sp)
|
||||
; N32-DAG: ld [[G21]], [[OFF21]]($sp)
|
||||
; N32-DAG: ld [[G22]], [[OFF22]]($sp)
|
||||
; N32-DAG: ld [[G23]], [[OFF23]]($sp)
|
||||
; N32-DAG: ld [[G28]], [[OFF28]]($sp)
|
||||
; N32-DAG: ld [[G30]], [[OFF30]]($sp)
|
||||
; N32-DAG: ld [[G31]], [[OFF31]]($sp)
|
||||
; N32: addiu $sp, $sp, 96
|
||||
|
||||
; N64: daddiu $sp, $sp, -96
|
||||
; N64-INV-NOT: sd $0,
|
||||
; N64-INV-NOT: sd $1,
|
||||
; N64-INV-NOT: sd $2,
|
||||
; N64-INV-NOT: sd $3,
|
||||
; N64-INV-NOT: sd $4,
|
||||
; N64-INV-NOT: sd $5,
|
||||
; N64-INV-NOT: sd $6,
|
||||
; N64-INV-NOT: sd $7,
|
||||
; N64-INV-NOT: sd $8,
|
||||
; N64-INV-NOT: sd $9,
|
||||
; N64-INV-NOT: sd $10,
|
||||
; N64-INV-NOT: sd $11,
|
||||
; N64-INV-NOT: sd $12,
|
||||
; N64-INV-NOT: sd $13,
|
||||
; N64-INV-NOT: sd $14,
|
||||
; N64-INV-NOT: sd $15,
|
||||
; N64-DAG: sd [[G16:\$16]], [[OFF16:[0-9]+]]($sp)
|
||||
; N64-DAG: sd [[G17:\$17]], [[OFF17:[0-9]+]]($sp)
|
||||
; N64-DAG: sd [[G18:\$18]], [[OFF18:[0-9]+]]($sp)
|
||||
; N64-DAG: sd [[G19:\$19]], [[OFF19:[0-9]+]]($sp)
|
||||
; N64-DAG: sd [[G20:\$20]], [[OFF20:[0-9]+]]($sp)
|
||||
; N64-DAG: sd [[G21:\$21]], [[OFF21:[0-9]+]]($sp)
|
||||
; N64-DAG: sd [[G22:\$22]], [[OFF22:[0-9]+]]($sp)
|
||||
; N64-DAG: sd [[G23:\$23]], [[OFF23:[0-9]+]]($sp)
|
||||
; N64-DAG: sd [[G30:\$fp]], [[OFF30:[0-9]+]]($sp)
|
||||
; N64-DAG: sd [[G31:\$fp]], [[OFF31:[0-9]+]]($sp)
|
||||
; N64-INV-NOT: sd $24,
|
||||
; N64-INV-NOT: sd $25,
|
||||
; N64-INV-NOT: sd $26,
|
||||
; N64-INV-NOT: sd $27,
|
||||
; N64-DAG: sd [[G28:\$gp]], [[OFF28:[0-9]+]]($sp)
|
||||
; N64-INV-NOT: sd $29,
|
||||
; N64-DAG: ld [[G16]], [[OFF16]]($sp)
|
||||
; N64-DAG: ld [[G17]], [[OFF17]]($sp)
|
||||
; N64-DAG: ld [[G18]], [[OFF18]]($sp)
|
||||
; N64-DAG: ld [[G19]], [[OFF19]]($sp)
|
||||
; N64-DAG: ld [[G20]], [[OFF20]]($sp)
|
||||
; N64-DAG: ld [[G21]], [[OFF21]]($sp)
|
||||
; N64-DAG: ld [[G22]], [[OFF22]]($sp)
|
||||
; N64-DAG: ld [[G23]], [[OFF23]]($sp)
|
||||
; N64-DAG: ld [[G28]], [[OFF28]]($sp)
|
||||
; N64-DAG: ld [[G30]], [[OFF30]]($sp)
|
||||
; N64-DAG: ld [[G31]], [[OFF31]]($sp)
|
||||
; N64: daddiu $sp, $sp, 96
|
@ -1,140 +0,0 @@
|
||||
; RUN: llc -march=mips < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
; RUN: llc -march=mipsel < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
|
||||
; RUN-TODO: llc -march=mips64 -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
; RUN-TODO: llc -march=mips64el -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
|
||||
; RUN: llc -march=mips64 -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
|
||||
; RUN: llc -march=mips64el -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
|
||||
|
||||
; RUN: llc -march=mips64 -target-abi n64 < %s | FileCheck --check-prefixes=ALL,N64 %s
|
||||
; RUN: llc -march=mips64el -target-abi n64 < %s | FileCheck --check-prefixes=ALL,N64 %s
|
||||
|
||||
; Test the memory layout for all ABI's and byte orders as specified by section
|
||||
; 4 of MD00305 (MIPS ABIs Described).
|
||||
; Bitfields are not covered since they are not available as a type in LLVM IR.
|
||||
;
|
||||
; The assembly directives deal with endianness so we don't need to account for
|
||||
; that.
|
||||
|
||||
; Deliberately request alignments that are too small for the target so we get
|
||||
; the minimum alignment instead of the preferred alignment.
|
||||
@byte = global i8 1, align 1
|
||||
@halfword = global i16 258, align 1
|
||||
@word = global i32 16909060, align 1
|
||||
@float = global float 1.0, align 1
|
||||
@dword = global i64 283686952306183, align 1
|
||||
@double = global double 1.0, align 1
|
||||
@pointer = global i8* @byte
|
||||
|
||||
; ALL-NOT: .p2align
|
||||
; ALL-LABEL: byte:
|
||||
; ALL: .byte 1
|
||||
; ALL: .size byte, 1
|
||||
|
||||
; ALL: .p2align 1
|
||||
; ALL-LABEL: halfword:
|
||||
; ALL: .2byte 258
|
||||
; ALL: .size halfword, 2
|
||||
|
||||
; ALL: .p2align 2
|
||||
; ALL-LABEL: word:
|
||||
; ALL: .4byte 16909060
|
||||
; ALL: .size word, 4
|
||||
|
||||
; ALL: .p2align 2
|
||||
; ALL-LABEL: float:
|
||||
; ALL: .4byte 1065353216
|
||||
; ALL: .size float, 4
|
||||
|
||||
; ALL: .p2align 3
|
||||
; ALL-LABEL: dword:
|
||||
; ALL: .8byte 283686952306183
|
||||
; ALL: .size dword, 8
|
||||
|
||||
; ALL: .p2align 3
|
||||
; ALL-LABEL: double:
|
||||
; ALL: .8byte 4607182418800017408
|
||||
; ALL: .size double, 8
|
||||
|
||||
; O32: .p2align 2
|
||||
; N32: .p2align 2
|
||||
; N64: .p2align 3
|
||||
; ALL-LABEL: pointer:
|
||||
; O32: .4byte byte
|
||||
; O32: .size pointer, 4
|
||||
; N32: .4byte byte
|
||||
; N32: .size pointer, 4
|
||||
; N64: .8byte byte
|
||||
; N64: .size pointer, 8
|
||||
|
||||
@byte_array = global [2 x i8] [i8 1, i8 2], align 1
|
||||
@halfword_array = global [2 x i16] [i16 1, i16 2], align 1
|
||||
@word_array = global [2 x i32] [i32 1, i32 2], align 1
|
||||
@float_array = global [2 x float] [float 1.0, float 2.0], align 1
|
||||
@dword_array = global [2 x i64] [i64 1, i64 2], align 1
|
||||
@double_array = global [2 x double] [double 1.0, double 2.0], align 1
|
||||
@pointer_array = global [2 x i8*] [i8* @byte, i8* @byte]
|
||||
|
||||
; ALL-NOT: .p2align
|
||||
; ALL-LABEL: byte_array:
|
||||
; ALL: .ascii "\001\002"
|
||||
; ALL: .size byte_array, 2
|
||||
|
||||
; ALL: .p2align 1
|
||||
; ALL-LABEL: halfword_array:
|
||||
; ALL: .2byte 1
|
||||
; ALL: .2byte 2
|
||||
; ALL: .size halfword_array, 4
|
||||
|
||||
; ALL: .p2align 2
|
||||
; ALL-LABEL: word_array:
|
||||
; ALL: .4byte 1
|
||||
; ALL: .4byte 2
|
||||
; ALL: .size word_array, 8
|
||||
|
||||
; ALL: .p2align 2
|
||||
; ALL-LABEL: float_array:
|
||||
; ALL: .4byte 1065353216
|
||||
; ALL: .4byte 1073741824
|
||||
; ALL: .size float_array, 8
|
||||
|
||||
; ALL: .p2align 3
|
||||
; ALL-LABEL: dword_array:
|
||||
; ALL: .8byte 1
|
||||
; ALL: .8byte 2
|
||||
; ALL: .size dword_array, 16
|
||||
|
||||
; ALL: .p2align 3
|
||||
; ALL-LABEL: double_array:
|
||||
; ALL: .8byte 4607182418800017408
|
||||
; ALL: .8byte 4611686018427387904
|
||||
; ALL: .size double_array, 16
|
||||
|
||||
; O32: .p2align 2
|
||||
; N32: .p2align 2
|
||||
; N64: .p2align 3
|
||||
; ALL-LABEL: pointer_array:
|
||||
; O32: .4byte byte
|
||||
; O32: .4byte byte
|
||||
; O32: .size pointer_array, 8
|
||||
; N32: .4byte byte
|
||||
; N32: .4byte byte
|
||||
; N32: .size pointer_array, 8
|
||||
; N64: .8byte byte
|
||||
; N64: .8byte byte
|
||||
; N64: .size pointer_array, 16
|
||||
|
||||
%mixed = type { i8, double, i16 }
|
||||
@mixed = global %mixed { i8 1, double 1.0, i16 515 }, align 1
|
||||
|
||||
; ALL: .p2align 3
|
||||
; ALL-LABEL: mixed:
|
||||
; ALL: .byte 1
|
||||
; ALL: .space 7
|
||||
; ALL: .8byte 4607182418800017408
|
||||
; ALL: .2byte 515
|
||||
; ALL: .space 6
|
||||
; ALL: .size mixed, 24
|
||||
|
||||
; Bitfields are not available in LLVM IR so we can't test them here.
|
12
external/llvm/test/CodeGen/Mips/cconv/pr33883.ll
vendored
12
external/llvm/test/CodeGen/Mips/cconv/pr33883.ll
vendored
@ -1,12 +0,0 @@
|
||||
; RUN: llc -march=mips -mcpu=mips32 < %s -o /dev/null
|
||||
|
||||
; Test that calls to vector intrinsics do not crash SelectionDAGBuilder.
|
||||
|
||||
define <4 x float> @_ZN4simd3foo17hebb969c5fb39a194E(<4 x float>) {
|
||||
start:
|
||||
%1 = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %0)
|
||||
|
||||
ret <4 x float> %1
|
||||
}
|
||||
|
||||
declare <4 x float> @llvm.sqrt.v4f32(<4 x float>)
|
@ -1,39 +0,0 @@
|
||||
; RUN: llc -march=mips < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
; RUN: llc -march=mipsel < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
|
||||
; RUN-TODO: llc -march=mips64 -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
; RUN-TODO: llc -march=mips64el -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
|
||||
; RUN: llc -march=mips64 -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
|
||||
; RUN: llc -march=mips64el -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
|
||||
|
||||
; RUN: llc -march=mips64 -target-abi n64 < %s | FileCheck --check-prefixes=ALL,N64 %s
|
||||
; RUN: llc -march=mips64el -target-abi n64 < %s | FileCheck --check-prefixes=ALL,N64 %s
|
||||
|
||||
; Test that O32 correctly reserved space for the four arguments, even when
|
||||
; there aren't any as per section 5 of MD00305 (MIPS ABIs Described).
|
||||
|
||||
declare void @foo() nounwind;
|
||||
|
||||
define void @reserved_space() nounwind {
|
||||
entry:
|
||||
call void @foo()
|
||||
ret void
|
||||
}
|
||||
|
||||
; ALL-LABEL: reserved_space:
|
||||
; O32: addiu $sp, $sp, -24
|
||||
; O32: sw $ra, 20($sp)
|
||||
; O32: lw $ra, 20($sp)
|
||||
; O32: addiu $sp, $sp, 24
|
||||
; Despite pointers being 32-bit wide on N32, the return pointer is saved as a
|
||||
; 64-bit pointer. I've yet to find a documentation reference for this quirk but
|
||||
; this behaviour matches GCC so I have considered it to be correct.
|
||||
; N32: addiu $sp, $sp, -16
|
||||
; N32: sd $ra, 8($sp)
|
||||
; N32: ld $ra, 8($sp)
|
||||
; N32: addiu $sp, $sp, 16
|
||||
; N64: daddiu $sp, $sp, -16
|
||||
; N64: sd $ra, 8($sp)
|
||||
; N64: ld $ra, 8($sp)
|
||||
; N64: daddiu $sp, $sp, 16
|
@ -1,46 +0,0 @@
|
||||
; RUN: llc -mtriple=mips-linux-gnu -mattr=+soft-float -relocation-model=static < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
; RUN: llc -mtriple=mipsel-linux-gnu -mattr=+soft-float -relocation-model=static < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
|
||||
; RUN-TODO: llc -mtriple=mips64-linux-gnu -mattr=+soft-float -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
; RUN-TODO: llc -mtriple=mips64el-linux-gnu -mattr=+soft-float -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
|
||||
|
||||
; RUN: llc -mtriple=mips64-linux-gnu -mattr=+soft-float -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
|
||||
; RUN: llc -mtriple=mips64el-linux-gnu -mattr=+soft-float -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
|
||||
|
||||
; RUN: llc -mtriple=mips64-linux-gnu -mattr=+soft-float -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,N64 %s
|
||||
; RUN: llc -mtriple=mips64el-linux-gnu -mattr=+soft-float -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,N64 %s
|
||||
|
||||
; Test the float returns for all ABI's and byte orders as specified by
|
||||
; section 5 of MD00305 (MIPS ABIs Described).
|
||||
|
||||
; We only test Linux because other OS's use different relocations and I don't
|
||||
; know if this is correct.
|
||||
|
||||
@float = global float zeroinitializer
|
||||
@double = global double zeroinitializer
|
||||
|
||||
define float @retfloat() nounwind {
|
||||
entry:
|
||||
%0 = load volatile float, float* @float
|
||||
ret float %0
|
||||
}
|
||||
|
||||
; ALL-LABEL: retfloat:
|
||||
; O32-DAG: lui [[R1:\$[0-9]+]], %hi(float)
|
||||
; O32-DAG: lw $2, %lo(float)([[R1]])
|
||||
; N32-DAG: lui [[R1:\$[0-9]+]], %hi(float)
|
||||
; N32-DAG: lw $2, %lo(float)([[R1]])
|
||||
; N64-DAG: lw $2, %lo(float)([[R1:\$[0-9+]]])
|
||||
|
||||
define double @retdouble() nounwind {
|
||||
entry:
|
||||
%0 = load volatile double, double* @double
|
||||
ret double %0
|
||||
}
|
||||
|
||||
; ALL-LABEL: retdouble:
|
||||
; O32-DAG: lw $2, %lo(double)([[R1:\$[0-9]+]])
|
||||
; O32-DAG: addiu [[R2:\$[0-9]+]], [[R1]], %lo(double)
|
||||
; O32-DAG: lw $3, 4([[R2]])
|
||||
; N32-DAG: ld $2, %lo(double)([[R1:\$[0-9]+]])
|
||||
; N64-DAG: ld $2, %lo(double)([[R1:\$[0-9]+]])
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user