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
{ $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"
{ { 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
<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 }