openhwgroup / corev-gcc

GNU General Public License v2.0
22 stars 23 forks source link

pseudo instruction "LA" not translating to correct instructions #92

Closed dd-vaibhavjain closed 10 months ago

dd-vaibhavjain commented 11 months ago

Toolchain release:

corev-openhw-gcc-centos7-20231128

Core:

CV32E40P v2 with PULP instuctions

Issue Description:

Running with this toolchain release, for some cases we see "LA" pseudo instruction does not translate into proper set of instructions:

Result with this toolchain version : (NOT Expected) test.S :

kernel_sp:
la x6, kernel_stack_end

Resulting elf/ test.objdump:

0000010c : la x6, kernel_stack_end 10c: 7fc18313 addi x6,x3,2044 # 21704

Only 1 instruction "addi" generated.

Whereas with previous toolchain release which I was using corev-openhw-gcc-centos7-20230905 : (Expected) The output for the same test was generated correctly as shown:

0000010c : la x6, kernel_stack_end 10c: 00021317 auipc x6,0x21 110: 5f830313 addi x6,x6,1528 # 21704

2 instructions auipc and addi generating and building correct label address.

Compilations command options used:

riscv32-corev-elf-gcc -DPULP
-Os -g -static -mabi=ilp32
-march=rv32imc_zicsr_zifencei_xcvhwlp1p0_xcvmem1p0_xcvmac1p0_xcvbi1p0_xcvalu1p0_xcvsimd1p0_xcvbitmanip1p0
-Wall -pedantic -nostartfiles -lcv-verif /TOOLCHAIN/corev-public-gcc-centos7-20231128/bin/../lib/gcc/riscv32-corev-elf/14.0.0/../../../../riscv32-corev-elf/bin/ld

Steps to Reproduce :

Simulator questasim (QUESTA_2023.2_1)

Embecosm toolchain: corev-openhw-gcc-centos7-20231128

setenv SIMULATOR vsim

git clone https://github.com/XavierAubert/core-v-verif.git cd core-v-verif git checkout cv32e40p/dev_dd (hash if required -> d6403a919f41c85185a86c3f75876727280f1842 )

cd cv32e40p/sim/uvmt/

make gen_corev-dv test TEST=corev_rand_pulp_hwloop_exception CFG=pulp TEST_CFG_FILE= SIMULATOR=vsim USE_ISS=yes COV=NO RUN_INDEX=1588395466 GEN_START_INDEX=1588395466 SEED=1588395466 CFG_PLUSARGS=+UVM_TIMEOUT=100000

Attached assembly and elf files: LA_issue.zip

MaryBennett commented 10 months ago

I have reproduced this issue. I will now look into solutions.

Here are my commands:

riscv32-corev-elf-as corev_rand_pulp_hwloop_exception_1588395466.S -c -mabi=ilp32 -march=rv32imc_zicsr_zifencei_xcvhwlp1p0_xcvmem1p0_xcvmac1p0_xcvsimd1p0_xcvbitmanip1p0_xcvalu1p0
riscv32-corev-elf-ld a.out -o ald.out
riscv32-corev-elf-objdump -dr ald.out

Using openhw/master, I also get:

0001010c <kernel_sp>:
   1010c:       7fc18313                addi    t1,gp,2044 # 31b44 <kernel_stack_end>
jeremybennett commented 10 months ago

I understand this is a linker issue, so it should be added as a binutils-gdb issue.

craigblackmore commented 10 months ago

@dd-vaibhavjain it looks like the auipc/addi was global pointer relaxed with the new toolchain. x3 is the global pointer register gp.

The linker enables GP relaxation if __global_pointer$ != 0. Your link.ld sets it to:

    __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,
                            MAX(__DATA_BEGIN__ + 0x800, __bss_end - 0x800));

When GP relaxation is enabled, gp should be initialized at startup to __global_pointer$ and the rest of the code should not modify gp.

Your assembly source initializes gp to 0 and then there are various other instructions that write to it.

If you want to disable GP relaxation, then set __global_pointer$ to 0 in link.ld or remove it completely.

If you want GP relaxation, then initialize gp to __global_pointer$ and refrain from using x3/gp in your assembly source.

The RISC-V psABI documents GP relaxation here and includes an example of recommended initialization: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#global-pointer-relaxation

Let me know if this resolves the issue.

pascalgouedo commented 10 months ago

Hi @craigblackmore

Thank you for the analysis and feedback.

As x3 registers seems to be used as a normal register by the random asm test generator and we are maybe not able to refrain it to update it, your advice seems to be to disable GP relaxation by removing global pointer initialization in the linker script. Am I right?

My fear is that for standard C compiled code or even benchmarks, removing GP relaxation would generate more instructions and then decrease performances.

So ideally we would need a linker script for randomly generated asm tests and another one for C code?

craigblackmore commented 10 months ago

As x3 registers seems to be used as a normal register by the random asm test generator and we are maybe not able to refrain it to update it, your advice seems to be to disable GP relaxation by removing global pointer initialization in the linker script. Am I right?

Yes, in the linker script either set __global_pointer$ = 0 or remove __global_pointer$ completely. Note, the latter would not work with crt0.S because _start references __global_pointer$, so you would get an undefined reference.

My fear is that for standard C compiled code or even benchmarks, removing GP relaxation would generate more instructions and then decrease performances.

So ideally we would need a linker script for randomly generated asm tests and another one for C code?

Yes, that's right. A different linker script so that we do not degrade the size/performance of normal C and asm code.