24.22.5.2. gem5 microops

Some gem5 instructions break down into multiple microops.

Microops are very similar to regular instructions, and show on the gem5 ExecAll trace format since that flag implies ExecMicro.

On aarch64 for example, one of the simplest microoped instructions is STP, which does the relatively complex operation of storing two values to memory at once, and is therefore a good candidate for being broken down into microops. We can observe it when executing:

./run \
  --arch arch64 \
  --emulator gem5 \
  --trace-insts-stdout \
  --userland userland/arch/aarch64/freestanding/linux/disassembly_test.S \
;

which contains in gem5’s broken-ish disassembly that the input:

stp x1, x2 [x0, 16]

generated the output:

  16500: system.cpu: A0 T0 : @_start+108    : stp
  16500: system.cpu: A0 T0 : @_start+108. 0 :   addxi_uop   ureg0, x0, #16 : IntAlu :  D=0x0000000000420010  flags=(IsInteger|IsMicroop|IsDelayedCommit|IsFirstMicroop)
  17000: system.cpu: A0 T0 : @_start+108. 1 :   strxi_uop   w1, [ureg0]  : MemWrite :  D=0x000000009abcdef0 A=0x420010  flags=(IsInteger|IsMemRef|IsStore|IsMicroop|IsDelayedCommit)
  17500: system.cpu: A0 T0 : @_start+108. 2 :   strxi_uop   w2, [ureg0, #8] : MemWrite :  D=0x0000000000000002 A=0x420018  flags=(IsInteger|IsMemRef|IsStore|IsMicroop|IsLastMicroop)

Where @_start+108. 0, @_start+108. 1 and @_start+108. 2 all happen at the same PC, and are therefore microops of STP.

From their names, which are of course not specified in the ARMv8 architecture reference manual, we guess that:

  • addxi_uop: adds 16

  • strxi_uop: stores one of the two members of the pair, like a regular STR

From the gem5 source code, we see that STP is a class LdpStp : public PairMemOp, and then the constructor of PairMemOp sets up the microops depending on the exact type of LDP/STP: