Transplant Clang 10.0 to replace gcc, assemble files will report error

Recently, I transplant Clang to replace GCC to compile a simple OS kernel, but I meeting some troubles now. When Clang compile a assemble file, Clang report error as follow, but this file can be compiled normally with GCC. So my question is that the assembly language format supported by Clang different from GCC?Or, the error below is just because some compile options of Clang are not configured correctly?

=====================================================
src/exception.S:103:18: error: register expected
LDR R1, [R2, EXCEPT_FRAME_OFFSET_PC]
^
src/exception.S:224:14: error: unknown token in expression
LDR R1, =#0x030F
^

ARM assembly language for gcc and clang is essentially the same, but it’s mostly tested on code generated by compilers. Hand-written assembler can get into various parsing edge cases, like the ones you’ve found. If you find issues, please file a bug.

Thank you for your reply, I don’t know what is the cause of this problem, is it a bug of Clang itself or I am missing some compile option when using Clang? Where can I find all the compilation options supported by Clang?

Now I have encountered a new problem, and it is also the error encountered in compiling the assembly file.Have you encountered similar problems?

src/dispatch.S:95:5: error: instruction requires: fp registers
vpush {s0};
^
src/dispatch.S:96:5: error: instruction requires: fp registers
vpop {s0};
^
src/dispatch.S:174:5: error: instruction requires: fp registers
vstmdbeq r0!, {d8-d15}
^
src/dispatch.S:175:10: error: incorrect condition in IT block; got ‘al’, but expected ‘eq’
stmfd r0!, {r14}
^
src/dispatch.S:210:5: error: instruction requires: fp registers
vldmiaeq r1!, {d8-d15}
^
src/dispatch.S:213:8: error: incorrect condition in IT block; got ‘al’, but expected ‘eq’
msr psp, r1
^

I might call it a missing feature, but yes, a bug.

You need to specify a target that has floating-point enabled to use floating-point instructions. (For example, using the command-line argument -mfpu=vfpv2, or using the .fpu assembler directive.)

clang expects you to write stmfdeq.

thank you for your help, as you say, the error:

src/dispatch.S:175:10: error: incorrect condition in IT block; got ‘al’, but expected ‘eq’
stmfd r0!, {r14}
^

src/dispatch.S:213:8: error: incorrect condition in IT block; got ‘al’, but expected ‘eq’
msr psp, r1
^

I replce stmfd with stmfdeq, and msr to msreq, it does work. no such errors will be reported.

but the error as

src/dispatch.S:95:5: error: instruction requires: fp registers
vpush {s0};
^

I try to use -mfpu=vfpv2 to repalce -mfloat-abi=softfp -mfpu=fpv4-sp-d16, it doesn’t work.

Can you list the complete flags you’re using? “instruction requires: fp registers” means you’re disabling floating-point instructions somehow.

these are the full flags :

-g -gdwarf-2 -O2 -fno-builtin -fno-pic  -funsigned-char -ffunction-sections -fdata-sections -Wall -Wno-pragmas -fstack-protector-strong -Wfloat-equal -Wformat=2 -nostdinc -nostdlib -std=gnu99 -Wpointer-arith -Wstrict-prototypes -fno-exceptions -pipe -fno-omit-frame-pointer -Winvalid-pch -fno-short-enums --target=arm-none-eabi -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -D__LITEOS__ -DSECUREC_IN_KERNEL=0 -D_ALL_SOURCE -DLOSCFG_KERNEL_CPP_EXCEPTIONS_SUPPORT -DTESTSTM32F429IGTX -DSTM32F429xx

I just tried those exact flags, and I’m not seeing an error message. At least with a file that just contains “vpush {s0}”. Maybe you have some asm directive in the file that’s disabling FP?

yes, the integral file is


.syntax unified
#ifdef LOSCFG_ARCH_ARM_V6M
.arch armv6-m
#elif defined(LOSCFG_ARCH_CORTEX_M33)
.arch armv8-m.main
#else
.arch armv7e-m
#endif
.thumb

.equ OS_NVIC_INT_CTRL,           0xE000ED04
.equ OS_NVIC_SYSPRI2,            0xE000ED20
.equ OS_NVIC_PENDSV_PRI,         0xF0F00000
.equ OS_NVIC_PENDSVSET,          0x10000000
.equ OS_TASK_STATUS_RUNNING,     0x0010

.section .text
.thumb

.type OsStartToRun, %function
.global OsStartToRun
OsStartToRun:
    .fnstart
    .cantunwind
    ldr     r4, =OS_NVIC_SYSPRI2
    ldr     r5, =OS_NVIC_PENDSV_PRI
    str     r5, [r4]

    ldr     r1, =g_oldTask
    str     r0, [r1]

    ldr     r1, =g_runTask
    str     r0, [r1]

    movs    r1, #2
    msr     CONTROL, r1
    ldrh    r7, [r0 , #4]

    movs    r6,  #OS_TASK_STATUS_RUNNING
    strh    r6,  [r0 , #4]

#ifdef LOSCFG_ARCH_ARM_V6M
    ldr     r3, [r0]
    adds    r3, r3, #36

    ldmfd   r3!, {r0-r2}
    adds    r3, r3, #4
    ldmfd   r3!, {R4-R7}

    msr     psp, r3
    subs    r3, r3, #20
    ldr     r3,  [r3]
#else
    ldr     r12, [r0]

    add     r12, r12, #36
    /* __VFP_FP__ is set by -mfpu; __SOFTFP__ is set by -mfloat-abi=soft. */
#if defined(__VFP_FP__) && !defined(__SOFTFP__)
    add     r12, r12, #4
#endif

    ldmfd   r12!, {R0-R7}

    msr     psp, r12

#ifdef LOSCFG_ARCH_FPU_ENABLE
    vpush   {s0};
    vpop    {s0};
#endif

#endif

    mov     lr, r5

    cpsie   I
    bx      r6
    .fnend

.type ArchIntLock, %function
.global ArchIntLock
ArchIntLock:
    .fnstart
    .cantunwind
    mrs     r0, PRIMASK
    cpsid   I
    bx      lr
    .fnend

.type ArchIntUnlock, %function
.global ArchIntUnlock
ArchIntUnlock:
    .fnstart
    .cantunwind
    mrs     r0, PRIMASK
    cpsie   I
    bx      lr
    .fnend

.type ArchIntRestore, %function
.global ArchIntRestore
ArchIntRestore:
    .fnstart
    .cantunwind
    msr     PRIMASK, r0
    bx      lr
    .fnend

.type OsTaskSchedule, %function
.global OsTaskSchedule
OsTaskSchedule:
    .fnstart
    .cantunwind
    ldr     r2, =OS_NVIC_INT_CTRL
    ldr     r3, =OS_NVIC_PENDSVSET
    str     r3, [r2]
    bx      lr
    .fnend

.type osPendSV, %function
.global osPendSV
osPendSV:
    .fnstart
    .cantunwind
    mrs     r12, PRIMASK
    cpsid   I

TaskSwitch:
    mrs     r0, psp

#ifdef LOSCFG_ARCH_ARM_V6M
    subs    r0, #36
    stmia   r0!, {r4-r7}
    mov     r3, r8
    mov     r4, r9
    mov     r5, r10
    mov     r6, r11
    mov     r7, r12
    stmia   r0!, {r3 - r7}

    subs    r0, #36
#else
#if defined(__VFP_FP__) && !defined(__SOFTFP__)
    /* when enter the exc or interrut, lr's value is EXC_RETURN. If FPCA = 1, the 4's bit of EXC_RETURN is 0. */
    tst     lr, #0x10
    it      eq
    vstmdbeq  r0!, {d8-d15} /* push VFP registers. */
    stmfd     r0!, {r14}
#endif
    stmfd   r0!, {r4-r12}
#endif
    ldr     r5, =g_oldTask
    ldr     r1, [r5]
    str     r0, [r1]

    ldr     r0, =g_runTask
    ldr     r0, [r0]
    /* g_oldTask = g_runTask */
    str     r0, [r5]
    ldr     r1, [r0]

#ifdef LOSCFG_ARCH_ARM_V6M
    adds    r1,   #16
    ldmfd   r1!, {r3-r7}

    mov     r8, r3
    mov     r9, r4
    mov     r10, r5
    mov     r11, r6
    mov     r12, r7
    subs    r1,  #36
    ldmfd   r1!, {r4-r7}

    adds    r1,   #20
#else
    ldmfd   r1!, {r4-r12}
#endif

#if defined(__VFP_FP__) && !defined(__SOFTFP__)
    ldmfd   r1!, {r14}
    tst     r14, #0x10
    it      eq
    vldmiaeq r1!, {d8-d15}
#endif

    msr     psp,  r1

    msr     PRIMASK, r12
    bx      lr
    .fnend

and this file is one file of a simple RTOS, if you compile this file separately, you need to add “-DLOSCFG_ARCH_FPU_ENABLE ” option