[ARM/Thumb] Make a function in arm while in Thumb triple

Hi,
I wanted to know if it was possible to force ARM backend to compile a function in ARM while the rest is in Thumb mode.
I tried the attributes which is used in GCC but it doesn’t work.

Here is what I tried:
https://pastebin.com/jCr5LPUY

Thanks in advance,
Uvekilledkenny

It's not possible I'm afraid. ARM/Thumb is per-file in Clang.

Tim.

Hi Dimitri,

As I know the following ACLE attributes are not supported in Clang/LLVM at the moment:

attribute((target(“arm”))) attribute

attribute((target(“thumb”))) attribute

But there is a workaround:

attribute((target(“no-thumb-mode”)))

attribute((target(“thumb-mode”)))

The attributes are propagated to a function declaration in IR by the frontend and the backend generated the code according to them:

$ cat test.c

attribute((target(“no-thumb-mode”))) int foo(void)

{

return 0;

}

int main(void)

{

return foo();

}

$ clang -nostdlib -target armv4t-none-eabi -mthumb -c test.c -emit-llvm -S -o -

; ModuleID = ‘test.c’

source_filename = “test.c”

target datalayout = “e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64”

target triple = “thumbv4t-none–eabi”

; Function Attrs: noinline nounwind

define i32 @foo() #0 {

ret i32 0

}

; Function Attrs: noinline nounwind

define i32 @main() #1 {

%1 = alloca i32, align 4

store i32 0, i32* %1, align 4

%2 = call i32 @foo()

ret i32 %2

}

attributes #0 = { noinline nounwind “correctly-rounded-divide-sqrt-fp-math”=“false” “disable-tail-calls”=“false” “less-precise-fpmad”=“false” “no-frame-pointer-elim”=“true” “no-frame-pointer-elim-non-leaf” “no-infs-fp-math”=“false” “no-jump-tables”=“false” “no-nans-fp-math”=“false” “no-signed-zeros-fp-math”=“false” “no-trapping-math”=“false” “stack-protector-buffer-size”=“8” “target-cpu”=“arm7tdmi” “target-features”=“+soft-float-abi,+strict-align,-thumb-mode” “unsafe-fp-math”=“false” “use-soft-float”=“false” }

attributes #1 = { noinline nounwind “correctly-rounded-divide-sqrt-fp-math”=“false” “disable-tail-calls”=“false” “less-precise-fpmad”=“false” “no-frame-pointer-elim”=“true” “no-frame-pointer-elim-non-leaf” “no-infs-fp-math”=“false” “no-jump-tables”=“false” “no-nans-fp-math”=“false” “no-signed-zeros-fp-math”=“false” “no-trapping-math”=“false” “stack-protector-buffer-size”=“8” “target-cpu”=“arm7tdmi” “target-features”=“+strict-align” “unsafe-fp-math”=“false” “use-soft-float”=“false” }

!llvm.module.flags = !{!0, !1}

!llvm.ident = !{!2}

!0 = !{i32 1, !“wchar_size”, i32 4}

!1 = !{i32 1, !“min_enum_size”, i32 4}

!2 = !{!“clang version 4.0.1 (branches/release_40 299654)”}

$ clang -nostdlib -target armv4t-none-eabi -mthumb -c test.c -S -o -

.text

.syntax unified

.eabi_attribute 67, “2.09” @ Tag_conformance

.cpu arm7tdmi

.eabi_attribute 6, 2 @ Tag_CPU_arch

.eabi_attribute 8, 1 @ Tag_ARM_ISA_use

.eabi_attribute 9, 1 @ Tag_THUMB_ISA_use

.eabi_attribute 17, 1 @ Tag_ABI_PCS_GOT_use

.eabi_attribute 20, 1 @ Tag_ABI_FP_denormal

.eabi_attribute 21, 1 @ Tag_ABI_FP_exceptions

.eabi_attribute 23, 3 @ Tag_ABI_FP_number_model

.eabi_attribute 34, 0 @ Tag_CPU_unaligned_access

.eabi_attribute 24, 1 @ Tag_ABI_align_needed

.eabi_attribute 25, 1 @ Tag_ABI_align_preserved

.eabi_attribute 38, 1 @ Tag_ABI_FP_16bit_format

.eabi_attribute 18, 4 @ Tag_ABI_PCS_wchar_t

.eabi_attribute 26, 2 @ Tag_ABI_enum_size

.eabi_attribute 14, 0 @ Tag_ABI_PCS_R9_use

.file “test.c”

‘+soft-float-abi’ is not a recognized feature for this target (ignoring feature)

‘+soft-float-abi’ is not a recognized feature for this target (ignoring feature)

.globl foo

.p2align 2

.type foo,%function

.code 32 @ @foo

foo:

.fnstart

@ BB#0:

mov r0, #0

bx lr

.Lfunc_end0:

.size foo, .Lfunc_end0-foo

.cantunwind

.fnend

.globl main

.p2align 1

.type main,%function

.code 16 @ @main

.thumb_func

main:

.fnstart

@ BB#0:

.save {r7, lr}

push {r7, lr}

.setfp r7, sp

add r7, sp, #0

.pad #8

sub sp, #8

movs r0, #0

str r0, [sp, #4]

bl foo

add sp, #8

pop {r7}

pop {r1}

mov lr, r1

bx lr

.Lfunc_end1:

.size main, .Lfunc_end1-main

.cantunwind

.fnend

.ident “clang version 4.0.1 (branches/release_40 299654)”

.section “.note.GNU-stack”,“”,%progbits

.eabi_attribute 30, 5 @ Tag_ABI_optimization_goals

Thanks,

Evgeny Astigeevich

Senior Compiler Engineer

Compilation Tools

ARM

Hi Dimitri,

As I know the following ACLE attributes are not supported in Clang/LLVM at
the moment:

__attribute__((target("arm"))) attribute

__attribute__((target("thumb"))) attribute

But there is a workaround:

__attribute__((target("no-thumb-mode")))

__attribute__((target("thumb-mode")))

Just curious. Why not provide target("arm") and target("thumb")?​

The attributes are propagated to a function declaration in IR by the
frontend and the backend generated the code according to them:

$ cat test.c

    __attribute__((target("no-thumb-mode"))) int foo(void)

    {

        return 0;

    }

    int main(void)

    {

        return foo();

    }

$ clang -nostdlib -target armv4t-none-eabi -mthumb -c test.c -emit-llvm -S
-o -

; ModuleID = 'test.c'

source_filename = "test.c"

target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"

target triple = "thumbv4t-none--eabi"

; Function Attrs: noinline nounwind

define i32 @foo() #0 {

  ret i32 0

}

; Function Attrs: noinline nounwind

define i32 @main() #1 {

  %1 = alloca i32, align 4

  store i32 0, i32* %1, align 4

  %2 = call i32 @foo()

ret i32 %2

}

attributes #0 = { noinline nounwind "correctly-rounded-divide-sqrt-fp-math"="false"
"disable-tail-calls"="false" "less-precise-fpmad"="false"
"no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
"no-infs-fp-math"="false" "no-jump-tables"="false"
"no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false"
"no-trapping-math"="false" "stack-protector-buffer-size"="8"
"target-cpu"="arm7tdmi" "target-features"="+soft-float-abi,+strict-align,
*-thumb-mode*" "unsafe-fp-math"="false" "use-soft-float"="false" }

attributes #1 = { noinline nounwind "correctly-rounded-divide-sqrt-fp-math"="false"
"disable-tail-calls"="false" "less-precise-fpmad"="false"
"no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
"no-infs-fp-math"="false" "no-jump-tables"="false"
"no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false"
"no-trapping-math"="false" "stack-protector-buffer-size"="8"
"target-cpu"="arm7tdmi" "target-features"="+strict-align"
"unsafe-fp-math"="false" "use-soft-float"="false" }

​I don't know if I am reading this wrong (not try this by myself)​. I see
you apply target("no-thumb-mode") attribute on function foo, yet foo's
attribute #0 has -thumb-mode? Seems to be contradiction?

Regards,
chenwj

Hi,

attribute((target(“no-thumb-mode”)))

attribute((target(“thumb-mode”)))

Just curious. Why not provide target(“arm”) and target(“thumb”)?​

I think there is no code converting them into corresponding target(“no-thumb-mode”) and target(“thumb-mode”) in the frontend.

I don’t know if I am reading this wrong (not try this by myself)​. I see you apply target(“no-thumb-mode”) attribute on function foo, yet foo’s attribute #0 has -thumb-mode? Seems to be contradiction?

In target-features “+attribute” means it is turned on, “-attribute” means it is turned off.

Thanks,

Evgeny

Wow, I am out of the loop! Thanks Evgeny.

Tim.