From 5e7b34b259ae56513294087426a237e778605f64 Mon Sep 17 00:00:00 2001 From: Irene Knapp Date: Thu, 28 May 2026 20:48:37 -0700 Subject: better documentation of parameter order for arithmetic instructions Force-Push: yes Change-Id: I02af0267657cf21fcf4e4d79457645da42f6798d --- amd64.e | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/amd64.e b/amd64.e index 2060a3d..f755112 100644 --- a/amd64.e +++ b/amd64.e @@ -746,6 +746,16 @@ s" :cc-greater" keyword ~ Arithmetic instructions ~ ~~~~~~~~~~~~~~~~~~~~~~~ +~ +~ Operations between two registers always have the target register as the +~ last parameter. Operations between a register and an immediate ALSO have the +~ target register as the last parameter, which is obvious for add-reg64-imm8 +~ but can be confusing for sub-reg64-imm8 or cmp-reg64-imm8. Also note what +~ this means for sub-reg64-reg64 and cmp-reg64-reg64. +~ +~ Every possible convention here leads to counterintuitive behavior in some +~ cases. This one has proven to be more memorable than the other obvious +~ choices, and that'll have to be enough. ~ (output point, source register, target register -- output point) : add-reg64-reg64 @@ -762,13 +772,13 @@ s" :cc-greater" keyword 3roll rex-w 0x03 pack8 3unroll reg64 swap addressing-indirect-reg64 ; -~ TODO needs description of argument order considerations -~ ~ (output point, immediate value, target register -- output point) : add-reg64-imm8 3roll rex-w 0x83 pack8 swap 0 swap addressing-reg64 swap pack8 ; +~ See above re: parameter order. +~ ~ (output point, source register, target register -- output point) : sub-reg64-reg64 3roll rex-w 0x2B pack8 3unroll @@ -779,14 +789,15 @@ s" :cc-greater" keyword 3roll rex-w 0x2B pack8 3unroll swap reg64 swap addressing-indirect-reg64 ; -~ TODO this convention is unlike other arithmetic operations. See the note -~ on cmp-reg64-imm8, pick one to go with, and document it. +~ See above re: parameter order. ~ ~ (output point, immediate value, target register -- output point) : sub-reg64-imm8 3roll rex-w 0x83 pack8 swap 5 swap addressing-reg64 swap pack8 ; +~ See above re: parameter order. +~ ~ (output point, source register, target register -- output point) : sbb-reg64-imm8 3roll rex-w 0x83 pack8 swap 3 swap addressing-reg64 @@ -885,6 +896,10 @@ s" :cc-greater" keyword ~ Control flow instructions ~ ~~~~~~~~~~~~~~~~~~~~~~~~~ +~ +~ The comparator instructions cmp and test follow the same argument-order +~ conventions as the arithmetic instructions: The target register always comes +~ last. See the arithmetic section for more discussion. ~ Pretend to subtract right from left, and set the flags the same way as if ~ we actually had. @@ -894,14 +909,7 @@ s" :cc-greater" keyword 3roll rex-w 0x3B pack8 3unroll reg64 swap addressing-reg64 ; -~ The parameter order here is weird, so take note. In a comparison between -~ a register and an immediate value, it makes sense to think of the register -~ as the target... but instead we opt to be consistent with the other cmp -~ instructions, which in turn are consistent with the sub instructions, in -~ which we put the left operand first because subtraction is not commutative. -~ TODO wrong, backwards, other choice -~ -~ TODO the immediate arithmetic instructions are all documented wrong +~ See above re: parameter order. ~ ~ (output point, immediate value, target register -- output point) : cmp-reg64-imm8 -- cgit 1.4.1