Skip to content

Commit

Permalink
[X86] Fix stack alignment for MCU target, by Anton Nadolskiy.
Browse files Browse the repository at this point in the history
This patch fixes stack alignments for MCU (should be aligned to 4 bytes).

Differential Revision: http://reviews.llvm.org/D15646

llvm-svn: 260375
  • Loading branch information
aturetsk committed Feb 10, 2016
1 parent d985eda commit 2396c38
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
9 changes: 7 additions & 2 deletions llvm/lib/Target/X86/X86TargetMachine.cpp
Expand Up @@ -73,25 +73,30 @@ static std::string computeDataLayout(const Triple &TT) {
// Some ABIs align 64 bit integers and doubles to 64 bits, others to 32.
if (TT.isArch64Bit() || TT.isOSWindows() || TT.isOSNaCl())
Ret += "-i64:64";
else if (TT.isOSIAMCU())
Ret += "-i64:32-f64:32";
else
Ret += "-f64:32:64";

// Some ABIs align long double to 128 bits, others to 32.
if (TT.isOSNaCl())
if (TT.isOSNaCl() || TT.isOSIAMCU())
; // No f80
else if (TT.isArch64Bit() || TT.isOSDarwin())
Ret += "-f80:128";
else
Ret += "-f80:32";

if (TT.isOSIAMCU())
Ret += "-f128:32";

// The registers can hold 8, 16, 32 or, in x86-64, 64 bits.
if (TT.isArch64Bit())
Ret += "-n8:16:32:64";
else
Ret += "-n8:16:32";

// The stack is aligned to 32 bits on some ABIs and 128 bits on others.
if (!TT.isArch64Bit() && TT.isOSWindows())
if ((!TT.isArch64Bit() && TT.isOSWindows()) || TT.isOSIAMCU())
Ret += "-a:0:32-S32";
else
Ret += "-S128";
Expand Down
47 changes: 47 additions & 0 deletions llvm/test/CodeGen/X86/mcu-abi.ll
Expand Up @@ -82,6 +82,8 @@ entry:
ret i32 %i1
}

%struct.S = type { i8 }

; CHECK-LABEL: test_lib_args:
; CHECK: movl %edx, %eax
; CHECK: calll __fixsfsi
Expand All @@ -108,5 +110,50 @@ define i32 @test_fp128(fp128* %ptr) #0 {

declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #1

; CHECK-LABEL: test_alignment_d:
; CHECK-NOT: andl {{.+}}, %esp
define void @test_alignment_d() #0 {
entry:
%d = alloca double
store double 2.000000e+00, double* %d
call void @food(double* inreg %d)
ret void
}

; CHECK-LABEL: test_alignment_i:
; CHECK-NOT: andl {{.+}}, %esp
define void @test_alignment_i() #0 {
entry:
%i = alloca i64
store i64 2, i64* %i
call void @fooi(i64* inreg %i)
ret void
}


; CHECK-LABEL: test_alignment_s:
; CHECK-NOT: andl {{.+}}, %esp
define void @test_alignment_s() #0 {
%s = alloca %struct.S, align 4
call void @foos(%struct.S* inreg %s)
ret void
}


; CHECK-LABEL: test_alignment_fp:
; CHECK-NOT: andl {{.+}}, %esp
define void @test_alignment_fp() #0 {
entry:
%f = alloca fp128
store fp128 0xL00000000000000004000000000000000, fp128* %f
call void @foofp(fp128* inreg %f)
ret void
}

declare void @food(double* inreg)
declare void @fooi(i64* inreg)
declare void @foos(%struct.S* inreg)
declare void @foofp(fp128* inreg)

attributes #0 = { nounwind "use-soft-float"="true"}
attributes #1 = { nounwind argmemonly }

0 comments on commit 2396c38

Please sign in to comment.