cpu.x86.assembler: enable zero extension for AND with small immediates

locals-and-roots
Björn Lindqvist 2016-05-20 12:41:27 +02:00
parent 4230d2502a
commit 973606b5e2
3 changed files with 19 additions and 9 deletions

View File

@ -2,6 +2,10 @@ USING: compiler.codegen.labels cpu.x86.assembler.private help.markup
help.syntax kernel math sequences ;
IN: cpu.x86.assembler
HELP: (MOV-I)
{ $values { "dst" "destination" } { "src" "immediate value" } }
{ $description "MOV where 'src' is immediate. If dst is a 64-bit register and the 'src' value fits in 32 bits, then zero extension is taken advantage of by downgrading 'dst' to a 32-bit register. That way, the instruction gets a shorter encoding." } ;
HELP: 1-operand
{ $values { "operand" "operand" } { "reg,rex.w,opcode" sequence } }
{ $description "Used for encoding some instructions with one operand." } ;
@ -29,9 +33,9 @@ HELP: MOV
{ $values { "dst" "destination" "src" "source" } }
{ $description "Moves a value from one place to another." } ;
HELP: (MOV-I)
{ $values { "dst" "destination" } { "src" "immediate value" } }
{ $description "MOV where 'src' is immediate. If dst is a 64-bit register and the 'src' value fits in 32 bits, then zero extension is taken advantage of by downgrading 'dst' to a 32-bit register. That way, the instruction gets a shorter encoding." } ;
HELP: immediate-1/4
{ $values { "dst" "dst" } { "imm" "imm" } { "reg,rex.w,opcode" } }
{ $description "If imm is a byte, compile the opcode and the byte. Otherwise, set the 8-bit operand flag in the opcode, and compile the cell. The 'reg' is not really a register, but a value for the 'reg' field of the mod-r/m byte." } ;
HELP: zero-extendable?
{ $values { "imm" integer } { "?" boolean } }

View File

@ -165,10 +165,6 @@ M: register displacement, drop ;
over integer? [ first3 0b10 opcode-or 3array ] when ;
: immediate-1/4 ( dst imm reg,rex.w,opcode -- )
! If imm is a byte, compile the opcode and the byte.
! Otherwise, set the 8-bit operand flag in the opcode, and
! compile the cell. The 'reg' is not really a register, but
! a value for the 'reg' field of the mod-r/m byte.
over fits-in-byte? [
immediate-fits-in-size-bit immediate-1
] [
@ -339,7 +335,9 @@ M: immediate SBB { 0b011 t 0x80 } immediate-1/4 ;
M: operand SBB 0o030 2-operand ;
GENERIC: AND ( dst src -- )
M: immediate AND { 0b100 t 0x80 } immediate-1/4 ;
M: immediate AND ( dst src -- )
dup zero-extendable? [ [ 32-bit-version-of ] dip ] when
{ 0b100 t 0x80 } immediate-1/4 ;
M: operand AND 0o040 2-operand ;
GENERIC: SUB ( dst src -- )
@ -357,7 +355,8 @@ M: immediate XOR { 0b110 t 0x80 } immediate-1/4 ;
M: operand XOR 0o060 2-operand ;
GENERIC: CMP ( dst src -- )
M: immediate CMP { 0b111 t 0x80 } immediate-1/4 ;
M: immediate CMP ( dst src -- )
{ 0b111 t 0x80 } immediate-1/4 ;
M: operand CMP 0o070 2-operand ;
GENERIC: TEST ( dst src -- )

View File

@ -30,6 +30,13 @@ cpu x86.64? [
[ RAX RAX 29 %add-imm ] B{ } make
] unit-test
! %and-imm
{
B{ 131 225 6 }
} [
[ RCX RCX 0x6 %and-imm ] B{ } make
] unit-test
! %alien-invoke
{ 1 } [
init-relocation init-gc-maps [