]> gitweb.factorcode.org Git - factor.git/commitdiff
cpu.x86.assembler: enable zero extension for AND with small immediates
authorBjörn Lindqvist <bjourne@gmail.com>
Fri, 20 May 2016 10:41:27 +0000 (12:41 +0200)
committerBjörn Lindqvist <bjourne@gmail.com>
Fri, 20 May 2016 10:42:27 +0000 (12:42 +0200)
basis/cpu/x86/assembler/assembler-docs.factor
basis/cpu/x86/assembler/assembler.factor
basis/cpu/x86/x86-tests.factor

index 0dae1baee8cd6c945fdc055f84ee958d5f59e162..9a880ae6bf790b17dae36a8febc2badbe075b0b8 100644 (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 } }
index 3d72112e19eaef4508c593aa43f9a2724426ec72..87e9bdd0a361e0bb211c8db74e7d6b155858559e 100644 (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 -- )
index b79ff87e7d67108ba9056dbcbf5755f0bbb821dc..178681004739d3fd9a83eb5c06c92cd6cad8ef51 100644 (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 [