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: