Register values in ARM exec trace results (from GEM5) when compared with disassembly of the executable

Viewed 65

I tried running a simple hello world on ARM and went through the "exec" debug trace. I also used the disassembly of the executable to compare the sequence and register values. While doing so,i came across two doubts:

  1. On the instruction "adds" being used instead of "cmn" but "xzr" not mentioned in the trace
  2. How "x0" and "w0" register is handled? Is "w0" the lower 32 bits of "x0"?

Details described below:

5896098: system.cpu_cluster.cpus: T0 : 0x421324 @_dl_discover_osversion+4    :   add   x0, sp, #120       : IntAlu :  D=0x0000007ffffefb58
...
....
6007986: system.cpu_cluster.cpus: T0 : 0x439b40 @__uname    :   movz   x8, #160, #0      : IntAlu :  D=0x00000000000000a0
6007986: system.cpu_cluster.cpus: T0 : 0x439b44 @__uname+4    :   svc   #0x0               : IntAlu :
6064596: system.cpu_cluster.cpus: T0 : 0x439b48 @__uname+8    :   adds   x0, #4095         : IntAlu :  D=0x0000000000000000
6064929: system.cpu_cluster.cpus: T0 : 0x439b4c @__uname+12    :   b.cs   <__uname+20>      : IntAlu :
6064929: system.cpu_cluster.cpus: T0 : 0x439b50 @__uname+16    :   ret                      : IntAlu :
6065928: system.cpu_cluster.cpus: T0 : 0x421334 @_dl_discover_osversion+20    :   add   x3, sp, #250       : IntAlu :  D=0x0000007ffffefbda
6065928: system.cpu_cluster.cpus: T0 : 0x421338 @_dl_discover_osversion+24    :   cbnz   w0, <_dl_discover_osversion+184> : IntAlu :
6066261: system.cpu_cluster.cpus: T0 : 0x42133c @_dl_discover_osversion+28    :   movz   w6, #0, #0        : IntAlu :  D=0x0000000000000000
6066594: system.cpu_cluster.cpus: T0 : 0x421340 @_dl_discover_osversion+32    :   movz   w0, #0, #0        : IntAlu :  D=0x0000000000000000

On doing the disassembly on the executable, we could see the following :

0000000000439b40 <__uname>:
  439b40: d2801408 mov x8, #0xa0                   // #160
  439b44: d4000001 svc #0x0
  439b48: b13ffc1f cmn x0, #0xfff               
  439b4c: 54000042 b.cs 439b54 <__uname+0x14>  // b.hs, b.nlast
  439b50: d65f03c0 ret

Doubt : in GEM5, " cmn x0, #0xfff " is treated as adds instead of cmn. But from the ARM isa document, cmn is identical to "adds xzr, Xn, #imm". So is the GEM5 internally following this format with xzr? or does GEM5 update x0 here as the trace doesnt show xzr?

Disassembly on the executable:

0000000000421320 <_dl_discover_osversion>:
  421320: d10803ff sub sp, sp, #0x200
  421324: 9101e3e0 add x0, sp, #0x78
  421328: a9007bfd stp x29, x30, [sp]
  42132c: 910003fd mov x29, sp
  421330: 94006204 bl 439b40 <__uname>
  421334: 9103ebe3 add x3, sp, #0xfa
  421338: 35000500 cbnz w0, 4213d8 <_dl_discover_osversion+0xb8>
  42133c: 52800006 mov w6, #0x0                   // #0
  421340: 52800000 mov w0, #0x0                   // #0

Doubt: From the GEM5 trace, i could see at the time of executing " cbnz w0, 4213d8", the value of x0 register = 0x0000007ffffefb58 (provided the "adds" case mentioned above didnt update "x0")

so x0 is having a non-zero value and its binary representation is: 0000000000000000000000000111111111111111111111101111101101011000

so w0 (lower 32 bits of x0) = 11111111111111101111101101011000

Since the w0 is non-zero, shouldnt it take a branch at " cbnz w0, 4213d8"?

Since GEM5 is not taking a branch, it means the w0 value is 0 at that point. So :

Does x0 and w0 are treated as separate registers instead of w0 being the lower 32 bits of x0?

because on the GEM5 trace, the last update made on "w0" is the following line: 5149845: system.cpu_cluster.cpus: T0 : 0x439dfc @brk+28 : movz w0, #0, #0 : IntAlu : D=0x0000000000000000

0 Answers
Related