[builtins][ARM] Replace call_apsr.S with inline asm

The %arm_call_apsr expansion doesn't work when config.clang is a clang
driver defaulting to a non-ARM arch. Rather than fix it, replace
call_apsr.S with inline asm in call_apsr.h, which also resolves the
FIXME added in D31259.

Maybe the `__attribute__((noinline,pcs("aapcs")))` attributes are
unnecessary on the static functions, but I was unsure what liberty the
compiler had to insert instructions that modified the condition codes,
so it seemed helpful.

Differential Revision: https://reviews.llvm.org/D82147
This commit is contained in:
Ryan Prichard 2020-06-18 23:47:18 -07:00
parent 9b7e24c2a5
commit 36f9947aac
7 changed files with 20 additions and 53 deletions

View File

@ -1,6 +1,5 @@
// REQUIRES: arm-target-arch || armv6m-target-arch
// RUN: %arm_call_apsr -o %t.aspr.o
// RUN: %clang_builtins %s %t.aspr.o %librt -o %t && %run %t
// RUN: %clang_builtins %s %librt -o %t && %run %t
#include <stdint.h>
#include <stdio.h>

View File

@ -1,6 +1,5 @@
// REQUIRES: arm-target-arch || armv6m-target-arch
// RUN: %arm_call_apsr -o %t.aspr.o
// RUN: %clang_builtins %s %t.aspr.o %librt -o %t && %run %t
// RUN: %clang_builtins %s %librt -o %t && %run %t
#include <stdint.h>
#include <stdio.h>

View File

@ -1,6 +1,5 @@
// REQUIRES: arm-target-arch || armv6m-target-arch
// RUN: %arm_call_apsr -o %t.aspr.o
// RUN: %clang_builtins %s %t.aspr.o %librt -o %t && %run %t
// RUN: %clang_builtins %s %librt -o %t && %run %t
#include <stdint.h>
#include <stdio.h>

View File

@ -1,6 +1,5 @@
// REQUIRES: arm-target-arch || armv6m-target-arch
// RUN: %arm_call_apsr -o %t.aspr.o
// RUN: %clang_builtins %s %t.aspr.o %librt -o %t && %run %t
// RUN: %clang_builtins %s %librt -o %t && %run %t
#include <stdint.h>
#include <stdio.h>

View File

@ -1,29 +0,0 @@
#include "../../../../lib/builtins/assembly.h"
.syntax unified
// __attribute__((pcs("aapcs")))
// int32_t call_apsr_d(double a, double b, void(*fn)(double, double)) {
// fn(a, b);
// return apsr;
// }
DEFINE_COMPILERRT_PRIVATE_FUNCTION(call_apsr_d)
push {r7, lr}
ldr r7, [sp, #8]
blx r7
mrs r0, apsr
pop {r7, pc}
END_COMPILERRT_FUNCTION(call_apsr_d)
// __attribute__((pcs("aapcs")))
// int32_t call_apsr_f(float a, float b, void(*fn)(float, float)) {
// fn(a, b);
// return apsr;
// }
DEFINE_COMPILERRT_PRIVATE_FUNCTION(call_apsr_f)
push {lr}
blx r2
mrs r0, apsr
pop {pc}
END_COMPILERRT_FUNCTION(call_apsr_f)

View File

@ -16,10 +16,22 @@ union cpsr {
uint32_t value;
};
extern __attribute__((pcs("aapcs")))
uint32_t call_apsr_f(float a, float b, __attribute__((pcs("aapcs"))) void (*fn)(float, float));
__attribute__((noinline, pcs("aapcs"))) static uint32_t call_apsr_f(float a, float b,
__attribute__((pcs("aapcs"))) void (*fn)(float, float)) {
uint32_t result;
fn(a, b);
asm volatile("mrs %0, apsr"
: "=r"(result));
return result;
}
extern __attribute__((pcs("aapcs")))
uint32_t call_apsr_d(double a, double b, __attribute__((pcs("aapcs"))) void (*fn)(double, double));
__attribute__((noinline, pcs("aapcs"))) static uint32_t call_apsr_d(double a, double b,
__attribute__((pcs("aapcs"))) void (*fn)(double, double)) {
uint32_t result;
fn(a, b);
asm volatile("mrs %0, apsr"
: "=r"(result));
return result;
}
#endif // CALL_APSR_H

View File

@ -87,10 +87,6 @@ def build_invocation(compile_flags):
return " " + " ".join([clang_wrapper, config.clang] + compile_flags) + " "
target_arch = config.target_arch
if (target_arch == "arm"):
target_arch = "armv7"
config.substitutions.append( ("%clang ", build_invocation(target_cflags)) )
config.substitutions.append( ("%clangxx ", build_invocation(target_cxxflags)) )
config.substitutions.append( ("%clang_builtins ", \
@ -98,14 +94,6 @@ config.substitutions.append( ("%clang_builtins ", \
config.substitutions.append( ("%clangxx_builtins ", \
build_invocation(clang_builtins_cxxflags)))
# FIXME: move the call_apsr.s into call_apsr.h as inline-asm.
# some ARM tests needs call_apsr.s
call_apsr_source = os.path.join(builtins_lit_source_dir, 'arm', 'call_apsr.S')
march_flag = '-march=' + target_arch
call_apsr_flags = ['-c', march_flag, call_apsr_source]
config.substitutions.append( ("%arm_call_apsr ", \
build_invocation(call_apsr_flags)) )
# Default test suffixes.
config.suffixes = ['.c', '.cpp']