0

This is code to read 64bit address space. Issue showed up with gcc 9.3.1, did not have issue with earlier version of gcc

    static inline void write_to_64bit_address(uint64_t address, 
    uint32_t data) {
    uint32_t address_upper = (uint32_t)(address >> 32);
    uint32_t address_lower = (uint32_t)(address);
    uint32_t smc_code = SMC_LONG_ADDRESS_WRITE_SINGLE;
    asm volatile("mov r0, %[smc_code]\n"
                 "mov r1, %[addr_upper]\n"
                 "mov r2, %[addr_lower]\n"
                 "mov r3, %[data_all]\n"
                 "mov r4, %[smc_zero]\n"
                 "mov r5, %[smc_zero]\n"
                 "mov r6, %[smc_zero]\n"
                 "smc #0\n"
                 :
                 : [smc_code] "r"(smc_code),
                   [addr_upper] "r"(address_upper),
                   [addr_lower] "r"(address_lower),
                   [data_all] "r"(data),
                   [smc_zero] "g"(SMC_ZERO)
                 : "r0","r1","r2","r3","r4", "r5", "r6");
}

I don't understand this assembly as well and learning. Can someone help.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 3
    Seems to work here: https://godbolt.org/z/8K4rqYKTe. How are `SMC_LONG_ADDRESS_WRITE_SINGLE` and `SMC_ZERO` defined? What compiler options are you using? Can you make a [mcve], in case this depends on the function you're inlining into? – Nate Eldredge Mar 30 '21 at 23:34
  • Yeah, even works with `-O0 -fPIC` on Godbolt, with/without `-mcpu=cortex-a53`. (GCC sometimes doesn't have as many free registers in un-optimized code, or doesn't CSE equal operands into the same input register, although this is more often a problem for addressing modes for different `"m"` operands). Are you using `-ffixed-r7` or anything that ties up another register pemanently? Or `register uint32_t foo asm("r0")` or something that could conflict with a clobber? – Peter Cordes Mar 31 '21 at 04:50
  • Also, normally write constraints to get the compiler to put stuff in the right register in the first place (using register-asm local vars to force it to pick that for `"r"`). Don't use `mov` as the first or last instruction of the asm template. Especially not reading `smc_zero` 3 times if it might be a memory operand instead of a small immediate. Anyway, that will let you tell the compiler which input values are modified or not by the `smc #0` instruction, so it doesn't have to reload them if it wants them after. – Peter Cordes Mar 31 '21 at 04:53

0 Answers0