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?
=====================================================
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