]> gitweb.factorcode.org Git - factor.git/commitdiff
cpu.x86.assembler: MOV zero extension for small immediates (#1593)
authorBjörn Lindqvist <bjourne@gmail.com>
Thu, 19 May 2016 21:02:48 +0000 (23:02 +0200)
committerBjörn Lindqvist <bjourne@gmail.com>
Thu, 19 May 2016 21:02:48 +0000 (23:02 +0200)
Instructions eg: mov rax, 123 can be equivalent mov eax, 123 which are
shorter.

basis/cpu/x86/assembler/assembler-docs.factor
basis/cpu/x86/assembler/assembler-tests.factor
basis/cpu/x86/assembler/assembler.factor

index 8a6228655dc7de34b5323b7fbf605678b49f6238..0dae1baee8cd6c945fdc055f84ee958d5f59e162 100644 (file)
@@ -1,5 +1,5 @@
 USING: compiler.codegen.labels cpu.x86.assembler.private help.markup
-help.syntax sequences ;
+help.syntax kernel math sequences ;
 IN: cpu.x86.assembler
 
 HELP: 1-operand
@@ -30,9 +30,17 @@ HELP: MOV
 { $description "Moves a value from one place to another." } ;
 
 HELP: (MOV-I)
-{ $values { "dst" "destination" "src" "immediate value" } }
-{ $description "MOV where the src is immediate." } ;
-
-ARTICLE: "cpu.x86.assembler" "X86 assembler" "This vocab implements an assembler for x86 architectures." ;
+{ $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: zero-extendable?
+{ $values { "imm" integer } { "?" boolean } }
+{ $description "All positive 32-bit numbers are zero extendable except for 0 which is the value used for relocations." } ;
+
+ARTICLE: "cpu.x86.assembler" "X86 assembler"
+"This vocab implements an assembler for x86 architectures."
+$nl
+"Instructions:"
+{ $subsections MOV } ;
 
 ABOUT: "cpu.x86.assembler"
index 745feec4c51f379df358540fd83a55ad46531785..64a749684c49ee64df9880233b14bc21ff85f493 100644 (file)
@@ -12,11 +12,8 @@ IN: cpu.x86.assembler.tests
 { { 136 235 } } [ [ BL CH MOV ] { } make ] unit-test
 
 ! immediate operands
-cell 4 = [
-    [ { 0xb9 0x01 0x00 0x00 0x00 } ] [ [ ECX 1 MOV ] { } make ] unit-test
-] [
-    [ { 0xb9 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 } ] [ [ ECX 1 MOV ] { } make ] unit-test
-] if
+[ { 0xb9 0x01 0x00 0x00 0x00 } ] [ [ ECX 1 MOV ] { } make ] unit-test
+[ { 0xb9 0x01 0x00 0x00 0x00 } ] [ [ RCX 1 MOV ] { } make ] unit-test
 
 { { 0x83 0xc1 0x01 } } [ [ ECX 1 ADD ] { } make ] unit-test
 { { 0x81 0xc1 0x96 0x00 0x00 0x00 } } [ [ ECX 150 ADD ] { } make ] unit-test
index 68f87071764b81ae185c642f7773c09fd0423b70..3d72112e19eaef4508c593aa43f9a2724426ec72 100644 (file)
@@ -212,13 +212,23 @@ M: operand POP { 0b000 f 0x8f } 1-operand ;
 
 <PRIVATE
 
+: zero-extendable? ( imm -- ? )
+    1 32 2^ 1 - between? ;
+
 GENERIC# (MOV-I) 1 ( dst src -- )
 
 M: register (MOV-I)
-    dup byte?
-    [ [ t 0xb0 short-operand ] [ 1, ] bi* ]
-    [ [ t 0xb8 short-operand ] [ cell, ] bi* ]
-    if ;
+    {
+        {
+            [ dup byte? ]
+            [ [ t 0xb0 short-operand ] [ 1, ] bi* ]
+        }
+        {
+            [ dup zero-extendable? ]
+            [ [ 32-bit-version-of t 0xb8 short-operand ] [ 4, ] bi* ]
+        }
+        [ [ t 0xb8 short-operand ] [ cell, ] bi* ]
+    } cond ;
 
 M: operand (MOV-I)
     { 0b000 t 0xc6 }