[Sbcl-devel] Disassembly of SSE instructions under x86-64

Hi,
attached is a patch to make the x86-64 disassembler understand the
SSE instructions.
The SSE instruction definitions were, in my opinion, written using
too much code duplication. Instead of making this worse when adding
the printer clauses I rewrote the definitions completely using
macrolets like the other ports do. SSE is encoded more regularly
than I would have believed before this exercise ;-), so despite the
added functionality the source code size remains nearly the same.
What's left to do: Write printers for LDMXCSR and STMXCSR.
Besides the obvious, namely that SSE instructions are disassembled,
and some added comments, the following things change, too:
- MOVSS and MOVSD used to always emit a REX prefix. They do this no
longer when it is unnecessary, that is, when no extended register
is involved. For example:
Currently:
F2480F1058F9 MOVSD XMM3, [RAX-7]
With the patch:
F20F1058F9 MOVSD XMM3, [RAX-7]
- The assembler does more error checking, for example the
float-to-integer conversion instructions check that the destination
is indeed a general-purpose register and not an XMM register and that
it has a suitable size.
- In MOVSS and MOVSD the assembler no longer uses TN-P to decide which
argument to encode as reg and which as reg/mem. Instead it checks
which of the arguments are XMM-register TNs. This has two effects:
* It is now additionally possible to use these instructions with
a stack TN as the source operand. (The current version throws
an error in this case, while already supporting the move in the
opposite direction.) That is:
(define-vop ...
(:temporary (:sc signed-stack) stack-temp)
(:temporary (:sc single-reg) register-temp)
(:generator ...
;; Already supported, used for example in SINGLE-FLOAT-BITS:
(inst movss stack-temp register-temp)
;; Additionally supported with the patch:
(inst movss register-temp stack-temp)))
* (Visible but of no import, mentioned only for completeness):
Register-register moves are encoded using the other one of the two
possible encodings:
Currently:
F30F11C2 MOVSS XMM2, XMM0
With the patch:
F30F10D0 MOVSS XMM2, XMM0
- I have changed the assembly of the four instructions CVTSD2SI,
CVTSS2SI, CVTTSD2SI and CVTTSS2SI (conversion of floats to integers)
to use the size of the integer argument as the operand size. (Their
current implementation ignores the size of the integer argument and
always treats it as qword, but the conversion instructions that work
in the opposite direction, CVTSI2SD and CVTSI2SS, already honor the
integer argument's size.)
I have checked that currently in all uses of the float-to-integer
conversion instructions the integer operand is qword-sized, so this
change does not affect existing code.
Some internal changes with no visible effect:
- Because the SSE instructions now more strictly determine which
operand size to use, MAYBE-EMIT-REX-PREFIX and MAYBE-EMIT-REX-FOR-EA
no longer need to support :FLOAT and :DOUBLE as the OPERAND-SIZE
argument. WIDTH-BITS does not, either.
- I optimised the tests for float registers in REG-TN-ENCODING and
MAYBE-EMIT-REX-PREFIX, so that TN-P is no longer doubly checked and
(in REG-TN-ENCODING) the name of the SB of the SC of the TN is not
calculated twice.
With kind regards
Lutz Euler

Thread view

Hi,
attached is a patch to make the x86-64 disassembler understand the
SSE instructions.
The SSE instruction definitions were, in my opinion, written using
too much code duplication. Instead of making this worse when adding
the printer clauses I rewrote the definitions completely using
macrolets like the other ports do. SSE is encoded more regularly
than I would have believed before this exercise ;-), so despite the
added functionality the source code size remains nearly the same.
What's left to do: Write printers for LDMXCSR and STMXCSR.
Besides the obvious, namely that SSE instructions are disassembled,
and some added comments, the following things change, too:
- MOVSS and MOVSD used to always emit a REX prefix. They do this no
longer when it is unnecessary, that is, when no extended register
is involved. For example:
Currently:
F2480F1058F9 MOVSD XMM3, [RAX-7]
With the patch:
F20F1058F9 MOVSD XMM3, [RAX-7]
- The assembler does more error checking, for example the
float-to-integer conversion instructions check that the destination
is indeed a general-purpose register and not an XMM register and that
it has a suitable size.
- In MOVSS and MOVSD the assembler no longer uses TN-P to decide which
argument to encode as reg and which as reg/mem. Instead it checks
which of the arguments are XMM-register TNs. This has two effects:
* It is now additionally possible to use these instructions with
a stack TN as the source operand. (The current version throws
an error in this case, while already supporting the move in the
opposite direction.) That is:
(define-vop ...
(:temporary (:sc signed-stack) stack-temp)
(:temporary (:sc single-reg) register-temp)
(:generator ...
;; Already supported, used for example in SINGLE-FLOAT-BITS:
(inst movss stack-temp register-temp)
;; Additionally supported with the patch:
(inst movss register-temp stack-temp)))
* (Visible but of no import, mentioned only for completeness):
Register-register moves are encoded using the other one of the two
possible encodings:
Currently:
F30F11C2 MOVSS XMM2, XMM0
With the patch:
F30F10D0 MOVSS XMM2, XMM0
- I have changed the assembly of the four instructions CVTSD2SI,
CVTSS2SI, CVTTSD2SI and CVTTSS2SI (conversion of floats to integers)
to use the size of the integer argument as the operand size. (Their
current implementation ignores the size of the integer argument and
always treats it as qword, but the conversion instructions that work
in the opposite direction, CVTSI2SD and CVTSI2SS, already honor the
integer argument's size.)
I have checked that currently in all uses of the float-to-integer
conversion instructions the integer operand is qword-sized, so this
change does not affect existing code.
Some internal changes with no visible effect:
- Because the SSE instructions now more strictly determine which
operand size to use, MAYBE-EMIT-REX-PREFIX and MAYBE-EMIT-REX-FOR-EA
no longer need to support :FLOAT and :DOUBLE as the OPERAND-SIZE
argument. WIDTH-BITS does not, either.
- I optimised the tests for float registers in REG-TN-ENCODING and
MAYBE-EMIT-REX-PREFIX, so that TN-P is no longer doubly checked and
(in REG-TN-ENCODING) the name of the SB of the SC of the TN is not
calculated twice.
With kind regards
Lutz Euler

Community

Help

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

I agree to receive quotes, newsletters and other information from sourceforge.net and its partners regarding IT services and products. I understand that I can withdraw my consent at any time. Please refer to our Privacy Policy or Contact Us for more details