| ; RUN: llc < %s -march=mips -mcpu=mips2 -relocation-model=pic | FileCheck %s \ |
| ; RUN: --check-prefixes=ALL,GP32 |
| ; RUN: llc < %s -march=mips -mcpu=mips32 -relocation-model=pic | FileCheck %s \ |
| ; RUN: --check-prefixes=ALL,GP32 |
| ; RUN: llc < %s -march=mips -mcpu=mips32r6 -relocation-model=pic | FileCheck %s \ |
| ; RUN: --check-prefixes=ALL,GP32 |
| ; RUN: llc < %s -march=mips64 -mcpu=mips3 -relocation-model=pic | FileCheck %s \ |
| ; RUN: --check-prefixes=ALL,GP64,N64 |
| ; RUN: llc < %s -march=mips64 -mcpu=mips64 -relocation-model=pic | FileCheck %s \ |
| ; RUN: --check-prefixes=ALL,GP64,N64 |
| ; RUN: llc < %s -march=mips64 -mcpu=mips64r6 -relocation-model=pic | FileCheck %s \ |
| ; RUN: --check-prefixes=ALL,GP64,N64 |
| ; RUN: llc < %s -march=mips64 -mcpu=mips3 -target-abi n32 -relocation-model=pic | FileCheck %s \ |
| ; RUN: --check-prefixes=ALL,GP64,N32 |
| ; RUN: llc < %s -march=mips64 -mcpu=mips64 -target-abi n32 -relocation-model=pic | FileCheck %s \ |
| ; RUN: --check-prefixes=ALL,GP64,N32 |
| ; RUN: llc < %s -march=mips64 -mcpu=mips64r6 -target-abi n32 -relocation-model=pic | FileCheck %s \ |
| ; RUN: --check-prefixes=ALL,GP64,N32 |
| |
| ; Check dynamic stack realignment in functions without variable-sized objects. |
| |
| declare void @helper_01(i32, i32, i32, i32, i32*) |
| |
| ; O32 ABI |
| define void @func_01() { |
| entry: |
| ; GP32-LABEL: func_01: |
| |
| ; prologue |
| ; FIXME: We are currently over-allocating stack space. This particular case |
| ; needs a frame of up to between 16 and 512-bytes but currently |
| ; allocates between 1024 and 1536 bytes |
| ; GP32: addiu $sp, $sp, -1024 |
| ; GP32: sw $ra, 1020($sp) |
| ; GP32: sw $fp, 1016($sp) |
| ; |
| ; GP32: move $fp, $sp |
| ; GP32: addiu $[[T0:[0-9]+|ra|gp]], $zero, -512 |
| ; GP32-NEXT: and $sp, $sp, $[[T0]] |
| |
| ; body |
| ; GP32: addiu $[[T1:[0-9]+]], $sp, 512 |
| ; GP32: sw $[[T1]], 16($sp) |
| |
| ; epilogue |
| ; GP32: move $sp, $fp |
| ; GP32: lw $fp, 1016($sp) |
| ; GP32: lw $ra, 1020($sp) |
| ; GP32: addiu $sp, $sp, 1024 |
| |
| %a = alloca i32, align 512 |
| call void @helper_01(i32 0, i32 0, i32 0, i32 0, i32* %a) |
| ret void |
| } |
| |
| declare void @helper_02(i32, i32, i32, i32, |
| i32, i32, i32, i32, i32*) |
| |
| ; N32/N64 ABIs |
| define void @func_02() { |
| entry: |
| ; GP64-LABEL: func_02: |
| |
| ; prologue |
| ; FIXME: We are currently over-allocating stack space. This particular case |
| ; needs a frame of up to between 16 and 512-bytes but currently |
| ; allocates between 1024 and 1536 bytes |
| ; N32: addiu $sp, $sp, -1024 |
| ; N64: daddiu $sp, $sp, -1024 |
| ; GP64: sd $ra, 1016($sp) |
| ; GP64: sd $fp, 1008($sp) |
| ; N32: sd $gp, 1000($sp) |
| ; |
| ; GP64: move $fp, $sp |
| ; N32: addiu $[[T0:[0-9]+|ra]], $zero, -512 |
| ; N64: daddiu $[[T0:[0-9]+|ra]], $zero, -512 |
| ; GP64-NEXT: and $sp, $sp, $[[T0]] |
| |
| ; body |
| ; N32: addiu $[[T1:[0-9]+]], $sp, 512 |
| ; N64: daddiu $[[T1:[0-9]+]], $sp, 512 |
| ; GP64: sd $[[T1]], 0($sp) |
| |
| ; epilogue |
| ; GP64: move $sp, $fp |
| ; N32: ld $gp, 1000($sp) |
| ; GP64: ld $fp, 1008($sp) |
| ; GP64: ld $ra, 1016($sp) |
| ; N32: addiu $sp, $sp, 1024 |
| ; N64: daddiu $sp, $sp, 1024 |
| |
| %a = alloca i32, align 512 |
| call void @helper_02(i32 0, i32 0, i32 0, i32 0, |
| i32 0, i32 0, i32 0, i32 0, i32* %a) |
| ret void |
| } |
| |
| ; Verify that we use $fp for referencing incoming arguments. |
| |
| declare void @helper_03(i32, i32, i32, i32, i32*, i32*) |
| |
| ; O32 ABI |
| define void @func_03(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32* %b) { |
| entry: |
| ; GP32-LABEL: func_03: |
| |
| ; body |
| ; FIXME: We are currently over-allocating stack space. |
| ; GP32-DAG: addiu $[[T0:[0-9]+]], $sp, 512 |
| ; GP32-DAG: sw $[[T0]], 16($sp) |
| ; GP32-DAG: lw $[[T1:[0-9]+]], 1040($fp) |
| ; GP32-DAG: sw $[[T1]], 20($sp) |
| |
| %a = alloca i32, align 512 |
| call void @helper_03(i32 0, i32 0, i32 0, i32 0, i32* %a, i32* %b) |
| ret void |
| } |
| |
| declare void @helper_04(i32, i32, i32, i32, |
| i32, i32, i32, i32, i32*, i32*) |
| |
| ; N32/N64 ABIs |
| define void @func_04(i32 %p0, i32 %p1, i32 %p2, i32 %p3, |
| i32 %p4, i32 %p5, i32 %p6, i32 %p7, |
| i32* %b) { |
| entry: |
| ; GP64-LABEL: func_04: |
| |
| ; body |
| ; FIXME: We are currently over-allocating stack space. |
| ; N32-DAG: addiu $[[T0:[0-9]+]], $sp, 512 |
| ; N64-DAG: daddiu $[[T0:[0-9]+]], $sp, 512 |
| ; GP64-DAG: sd $[[T0]], 0($sp) |
| ; GP64-DAG: ld $[[T1:[0-9]+]], 1024($fp) |
| ; GP64-DAG: sd $[[T1]], 8($sp) |
| |
| %a = alloca i32, align 512 |
| call void @helper_04(i32 0, i32 0, i32 0, i32 0, |
| i32 0, i32 0, i32 0, i32 0, i32* %a, i32* %b) |
| ret void |
| } |
| |
| ; Check dynamic stack realignment in functions with variable-sized objects. |
| |
| ; O32 ABI |
| define void @func_05(i32 %sz) { |
| entry: |
| ; GP32-LABEL: func_05: |
| |
| ; prologue |
| ; FIXME: We are currently over-allocating stack space. |
| ; GP32: addiu $sp, $sp, -1024 |
| ; GP32: sw $fp, 1020($sp) |
| ; GP32: sw $23, 1016($sp) |
| ; |
| ; GP32: move $fp, $sp |
| ; GP32: addiu $[[T0:[0-9]+|gp]], $zero, -512 |
| ; GP32-NEXT: and $sp, $sp, $[[T0]] |
| ; GP32-NEXT: move $23, $sp |
| |
| ; body |
| ; GP32: addiu $[[T1:[0-9]+]], $zero, 222 |
| ; GP32: sw $[[T1]], 508($23) |
| |
| ; epilogue |
| ; GP32: move $sp, $fp |
| ; GP32: lw $23, 1016($sp) |
| ; GP32: lw $fp, 1020($sp) |
| ; GP32: addiu $sp, $sp, 1024 |
| |
| %a0 = alloca i32, i32 %sz, align 512 |
| %a1 = alloca i32, align 4 |
| |
| store volatile i32 111, i32* %a0, align 512 |
| store volatile i32 222, i32* %a1, align 4 |
| |
| ret void |
| } |
| |
| ; N32/N64 ABIs |
| define void @func_06(i32 %sz) { |
| entry: |
| ; GP64-LABEL: func_06: |
| |
| ; prologue |
| ; FIXME: We are currently over-allocating stack space. |
| ; N32: addiu $sp, $sp, -1024 |
| ; N64: daddiu $sp, $sp, -1024 |
| ; GP64: sd $fp, 1016($sp) |
| ; GP64: sd $23, 1008($sp) |
| ; |
| ; GP64: move $fp, $sp |
| ; GP64: addiu $[[T0:[0-9]+|gp]], $zero, -512 |
| ; GP64-NEXT: and $sp, $sp, $[[T0]] |
| ; GP64-NEXT: move $23, $sp |
| |
| ; body |
| ; GP64: addiu $[[T1:[0-9]+]], $zero, 222 |
| ; GP64: sw $[[T1]], 508($23) |
| |
| ; epilogue |
| ; GP64: move $sp, $fp |
| ; GP64: ld $23, 1008($sp) |
| ; GP64: ld $fp, 1016($sp) |
| ; N32: addiu $sp, $sp, 1024 |
| ; N64: daddiu $sp, $sp, 1024 |
| |
| %a0 = alloca i32, i32 %sz, align 512 |
| %a1 = alloca i32, align 4 |
| |
| store volatile i32 111, i32* %a0, align 512 |
| store volatile i32 222, i32* %a1, align 4 |
| |
| ret void |
| } |
| |
| ; Verify that we use $fp for referencing incoming arguments and $sp for |
| ; building outbound arguments for nested function calls. |
| |
| ; O32 ABI |
| define void @func_07(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32 %sz) { |
| entry: |
| ; GP32-LABEL: func_07: |
| |
| ; body |
| ; FIXME: We are currently over-allocating stack space. |
| ; GP32-DAG: lw $[[T0:[0-9]+]], 1040($fp) |
| ; |
| ; GP32-DAG: addiu $[[T1:[0-9]+]], $zero, 222 |
| ; GP32-DAG: sw $[[T1]], 508($23) |
| ; |
| ; GP32-DAG: sw $[[T2:[0-9]+]], 16($sp) |
| |
| %a0 = alloca i32, i32 %sz, align 512 |
| %a1 = alloca i32, align 4 |
| |
| store volatile i32 111, i32* %a0, align 512 |
| store volatile i32 222, i32* %a1, align 4 |
| |
| call void @helper_01(i32 0, i32 0, i32 0, i32 0, i32* %a1) |
| |
| ret void |
| } |
| |
| ; N32/N64 ABIs |
| define void @func_08(i32 %p0, i32 %p1, i32 %p2, i32 %p3, |
| i32 %p4, i32 %p5, i32 %p6, i32 %p7, |
| i32 %sz) { |
| entry: |
| ; GP64-LABEL: func_08: |
| |
| ; body |
| ; FIXME: We are currently over-allocating stack space. |
| ; N32-DAG: lw $[[T0:[0-9]+]], 1028($fp) |
| ; N64-DAG: lwu $[[T0:[0-9]+]], 1028($fp) |
| ; |
| ; GP64-DAG: addiu $[[T1:[0-9]+]], $zero, 222 |
| ; GP64-DAG: sw $[[T1]], 508($23) |
| ; |
| ; GP64-DAG: sd $[[T2:[0-9]+]], 0($sp) |
| |
| %a0 = alloca i32, i32 %sz, align 512 |
| %a1 = alloca i32, align 4 |
| |
| store volatile i32 111, i32* %a0, align 512 |
| store volatile i32 222, i32* %a1, align 4 |
| |
| call void @helper_02(i32 0, i32 0, i32 0, i32 0, |
| i32 0, i32 0, i32 0, i32 0, i32* %a1) |
| ret void |
| } |
| |
| ; Check that we do not perform dynamic stack realignment in the presence of |
| ; the "no-realign-stack" function attribute. |
| define void @func_09() "no-realign-stack" { |
| entry: |
| ; ALL-LABEL: func_09: |
| |
| ; ALL-NOT: and $sp, $sp, $[[T0:[0-9]+|ra|gp]] |
| |
| %a = alloca i32, align 512 |
| call void @helper_01(i32 0, i32 0, i32 0, i32 0, i32* %a) |
| ret void |
| } |
| |
| define void @func_10(i32 %sz) "no-realign-stack" { |
| entry: |
| ; ALL-LABEL: func_10: |
| |
| ; ALL-NOT: and $sp, $sp, $[[T0:[0-9]+|ra|gp]] |
| |
| %a0 = alloca i32, i32 %sz, align 512 |
| %a1 = alloca i32, align 4 |
| |
| store volatile i32 111, i32* %a0, align 512 |
| store volatile i32 222, i32* %a1, align 4 |
| |
| ret void |
| } |