Stream: cranelift

Topic: Program counter behavior


view this post on Zulip Vulcain (Jul 29 2024 at 15:54):

Hey :wave:

I compiled this module with cranelift (aarch64) :

(module
    (func (export "run") (param $p i32) (result i32)
      (block
        (block
          (block
            (block
                (local.get $p)
                (br_table
                     2   ;; p == 0 => (br 2)
                     1   ;; p == 1 => (br 1)
                     0   ;; p == 2 => (br 0)
                     3)  ;; else => (br 3)
                )
            ;; Target for (br 0)
            (i32.const 100)
            (return)
          )
          ;; Target for (br 1)
          (i32.const 101)
          (return)
        )
        ;; Target for (br 2)
        (i32.const 102)
        (return)
      )
      ;; Target for (br 3)
      (i32.const 103)
      (return)
    )
)

The output is

00000000    pacibz
00000004    stp x29, x30, [sp, #-0x10]!
00000008    mov x29, sp
0000000c    cmp w4, #3
00000010    b.hs #0x68
00000014    csel x9, xzr, x4, hs
00000018    csdb
0000001c    adr x8, #0x2c
00000020    ldrsw x9, [x8, w9, uxtw #2]
00000024    add x8, x8, x9
00000028    br x8
0000002c    .byte 0x2c, 0x00, 0x00, 0x00
00000030    .byte 0x1c, 0x00, 0x00, 0x00
00000034    .byte 0x0c, 0x00, 0x00, 0x00
00000038    mov w2, #0x64
0000003c    ldp x29, x30, [sp], #0x10
00000040    autibz
00000044    ret
00000048    mov w2, #0x65
0000004c    ldp x29, x30, [sp], #0x10
00000050    autibz
00000054    ret
00000058    mov w2, #0x66
0000005c    ldp x29, x30, [sp], #0x10
00000060    autibz
00000064    ret
00000068    mov w2, #0x67
0000006c    ldp x29, x30, [sp], #0x10
00000070    autibz
00000074    ret

I don't understand the instruction 0000001c adr x8, #0x2c. adr is supposed to add 0x2c to the program counter, but then, it would read the address 0x48. However, it seems to read the address 0x2c.

Can someone explain how this work ? Thank you :smile:

view this post on Zulip Alex Crichton (Jul 29 2024 at 16:45):

Is that perhaps the assembler de-sugaring #0x2c rather than the immediate in the instruction itself? (I'm not familiar enough with instruction formats on aarch64 myself to say for sure)

view this post on Zulip Vulcain (Jul 29 2024 at 16:53):

I tried to copy the generated code and assemble it, and it reads 0x48. Then I read the runtime code to find answers. From my understanding, the code is cast to a rust closure. So yes, if it is not the runtime that changes the program counter behavior, it might be a weird disassembly :shrug:

view this post on Zulip Amanieu (Jul 29 2024 at 17:09):

The disassembly shows the target address, not the immediate that is added to PC.

view this post on Zulip Vulcain (Jul 29 2024 at 17:11):

Thank you :blush:


Last updated: Nov 22 2024 at 17:03 UTC