2005-01-08 16:43:18 -05:00
|
|
|
! Copyright (C) 2005 Slava Pestov.
|
2005-05-07 22:39:00 -04:00
|
|
|
! See http://factor.sf.net/license.txt for BSD license.
|
2006-08-08 01:38:32 -04:00
|
|
|
USING: arrays compiler errors generic io kernel kernel-internals
|
2006-05-15 01:01:47 -04:00
|
|
|
math namespaces parser sequences words ;
|
2006-04-29 17:32:15 -04:00
|
|
|
IN: assembler
|
2005-12-02 02:25:44 -05:00
|
|
|
|
|
|
|
! A postfix assembler for x86 and AMD64.
|
2005-01-08 16:43:18 -05:00
|
|
|
|
2005-12-23 01:41:33 -05:00
|
|
|
! In 32-bit mode, { 1234 } is absolute indirect addressing.
|
|
|
|
! In 64-bit mode, { 1234 } is RIP-relative.
|
|
|
|
! Beware!
|
|
|
|
|
2006-08-08 01:38:32 -04:00
|
|
|
: 4, 4 >le % ; inline
|
|
|
|
: cell, cell >le % ; inline
|
|
|
|
|
2006-02-23 19:01:12 -05:00
|
|
|
#! Extended AMD64 registers (R8-R15) return true.
|
2005-12-02 02:25:44 -05:00
|
|
|
GENERIC: extended? ( op -- ? )
|
|
|
|
|
|
|
|
M: object extended? drop f ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
|
|
|
( Register operands -- eg, ECX )
|
2005-12-14 20:29:32 -05:00
|
|
|
: define-register ( symbol num size -- )
|
|
|
|
>r dupd "register" set-word-prop r>
|
|
|
|
"register-size" set-word-prop ;
|
2005-12-02 02:25:44 -05:00
|
|
|
|
|
|
|
! x86 registers
|
2005-12-14 20:29:32 -05:00
|
|
|
SYMBOL: AX \ AX 0 16 define-register
|
|
|
|
SYMBOL: CX \ CX 1 16 define-register
|
|
|
|
SYMBOL: DX \ DX 2 16 define-register
|
|
|
|
SYMBOL: BX \ BX 3 16 define-register
|
|
|
|
SYMBOL: SP \ SP 4 16 define-register
|
|
|
|
SYMBOL: BP \ BP 5 16 define-register
|
|
|
|
SYMBOL: SI \ SI 6 16 define-register
|
|
|
|
SYMBOL: DI \ DI 7 16 define-register
|
|
|
|
|
|
|
|
SYMBOL: EAX \ EAX 0 32 define-register
|
|
|
|
SYMBOL: ECX \ ECX 1 32 define-register
|
|
|
|
SYMBOL: EDX \ EDX 2 32 define-register
|
|
|
|
SYMBOL: EBX \ EBX 3 32 define-register
|
|
|
|
SYMBOL: ESP \ ESP 4 32 define-register
|
|
|
|
SYMBOL: EBP \ EBP 5 32 define-register
|
|
|
|
SYMBOL: ESI \ ESI 6 32 define-register
|
|
|
|
SYMBOL: EDI \ EDI 7 32 define-register
|
2005-12-02 02:25:44 -05:00
|
|
|
|
2006-01-25 01:18:12 -05:00
|
|
|
SYMBOL: XMM0 \ XMM0 0 128 define-register
|
|
|
|
SYMBOL: XMM1 \ XMM1 1 128 define-register
|
|
|
|
SYMBOL: XMM2 \ XMM2 2 128 define-register
|
|
|
|
SYMBOL: XMM3 \ XMM3 3 128 define-register
|
|
|
|
SYMBOL: XMM4 \ XMM4 4 128 define-register
|
|
|
|
SYMBOL: XMM5 \ XMM5 5 128 define-register
|
|
|
|
SYMBOL: XMM6 \ XMM6 6 128 define-register
|
|
|
|
SYMBOL: XMM7 \ XMM7 7 128 define-register
|
2006-01-24 20:20:20 -05:00
|
|
|
|
2006-02-23 19:01:12 -05:00
|
|
|
! AMD64 registers
|
|
|
|
SYMBOL: RAX \ RAX 0 64 define-register
|
|
|
|
SYMBOL: RCX \ RCX 1 64 define-register
|
|
|
|
SYMBOL: RDX \ RDX 2 64 define-register
|
|
|
|
SYMBOL: RBX \ RBX 3 64 define-register
|
|
|
|
SYMBOL: RSP \ RSP 4 64 define-register
|
|
|
|
SYMBOL: RBP \ RBP 5 64 define-register
|
|
|
|
SYMBOL: RSI \ RSI 6 64 define-register
|
|
|
|
SYMBOL: RDI \ RDI 7 64 define-register
|
|
|
|
SYMBOL: R8 \ R8 8 64 define-register
|
|
|
|
SYMBOL: R9 \ R9 9 64 define-register
|
|
|
|
SYMBOL: R10 \ R10 10 64 define-register
|
|
|
|
SYMBOL: R11 \ R11 11 64 define-register
|
|
|
|
SYMBOL: R12 \ R12 12 64 define-register
|
|
|
|
SYMBOL: R13 \ R13 13 64 define-register
|
|
|
|
SYMBOL: R14 \ R14 14 64 define-register
|
|
|
|
SYMBOL: R15 \ R15 15 64 define-register
|
|
|
|
|
|
|
|
SYMBOL: XMM8 \ XMM8 8 128 define-register
|
|
|
|
SYMBOL: XMM9 \ XMM9 9 128 define-register
|
|
|
|
SYMBOL: XMM10 \ XMM10 10 128 define-register
|
|
|
|
SYMBOL: XMM11 \ XMM11 11 128 define-register
|
|
|
|
SYMBOL: XMM12 \ XMM12 12 128 define-register
|
|
|
|
SYMBOL: XMM13 \ XMM13 13 128 define-register
|
|
|
|
SYMBOL: XMM14 \ XMM14 14 128 define-register
|
|
|
|
SYMBOL: XMM15 \ XMM15 15 128 define-register
|
|
|
|
|
2005-03-05 14:45:23 -05:00
|
|
|
PREDICATE: word register "register" word-prop ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
2006-01-31 21:31:53 -05:00
|
|
|
PREDICATE: register register-16 "register-size" word-prop 16 = ;
|
2005-12-02 02:25:44 -05:00
|
|
|
PREDICATE: register register-32 "register-size" word-prop 32 = ;
|
|
|
|
PREDICATE: register register-64 "register-size" word-prop 64 = ;
|
2006-01-25 01:18:12 -05:00
|
|
|
PREDICATE: register register-128 "register-size" word-prop 128 = ;
|
2005-12-02 02:25:44 -05:00
|
|
|
|
2006-03-19 21:24:06 -05:00
|
|
|
M: register extended? "register" word-prop 7 > ;
|
|
|
|
|
2006-02-23 19:01:12 -05:00
|
|
|
( Addressing modes )
|
|
|
|
TUPLE: indirect base index scale displacement ;
|
|
|
|
|
2006-03-19 21:24:06 -05:00
|
|
|
M: indirect extended? indirect-base extended? ;
|
|
|
|
|
2006-02-23 19:01:12 -05:00
|
|
|
: canonicalize-EBP
|
|
|
|
#! { EBP } ==> { EBP 0 }
|
2006-03-19 21:24:06 -05:00
|
|
|
dup indirect-base { EBP RBP R13 } memq? [
|
2006-02-23 19:01:12 -05:00
|
|
|
dup indirect-displacement [
|
|
|
|
drop
|
|
|
|
] [
|
|
|
|
0 swap set-indirect-displacement
|
|
|
|
] if
|
|
|
|
] [
|
|
|
|
drop
|
|
|
|
] if ;
|
|
|
|
|
|
|
|
: canonicalize-ESP
|
|
|
|
#! { ESP } ==> { ESP ESP }
|
2006-03-19 21:24:06 -05:00
|
|
|
dup indirect-base { ESP RSP R12 } memq? [
|
2006-02-23 19:01:12 -05:00
|
|
|
dup indirect-base swap set-indirect-index
|
|
|
|
] [
|
|
|
|
drop
|
|
|
|
] if ;
|
|
|
|
|
|
|
|
: canonicalize ( indirect -- )
|
|
|
|
#! Modify the indirect to work around certain addressing mode
|
|
|
|
#! quirks.
|
|
|
|
dup canonicalize-EBP canonicalize-ESP ;
|
|
|
|
|
2006-02-23 20:22:18 -05:00
|
|
|
C: indirect ( base index scale displacement -- indirect )
|
|
|
|
[ set-indirect-displacement ] keep
|
|
|
|
[ set-indirect-scale ] keep
|
|
|
|
[ set-indirect-index ] keep
|
|
|
|
[ set-indirect-base ] keep
|
|
|
|
dup canonicalize ;
|
2006-02-23 19:01:12 -05:00
|
|
|
|
2006-02-23 20:22:18 -05:00
|
|
|
: [] ( reg/displacement -- indirect )
|
|
|
|
dup integer? [ >r f f f r> ] [ f f f ] if <indirect> ;
|
2006-02-23 19:01:12 -05:00
|
|
|
|
2006-02-23 20:22:18 -05:00
|
|
|
: [+] ( reg displacement -- indirect )
|
|
|
|
dup integer? [ >r f f r> ] [ f f ] if <indirect> ;
|
2006-02-23 19:01:12 -05:00
|
|
|
|
|
|
|
: reg-code "register" word-prop 7 bitand ;
|
|
|
|
|
2006-02-23 20:22:18 -05:00
|
|
|
: indirect-base* indirect-base [ EBP ] unless* reg-code ;
|
2006-02-23 19:01:12 -05:00
|
|
|
|
2006-02-23 20:22:18 -05:00
|
|
|
: indirect-index* indirect-index [ ESP ] unless* reg-code ;
|
|
|
|
|
|
|
|
: indirect-scale* indirect-scale [ 0 ] unless* ;
|
2006-02-23 19:01:12 -05:00
|
|
|
|
|
|
|
GENERIC: sib-present?
|
|
|
|
|
2006-08-15 03:01:24 -04:00
|
|
|
M: indirect sib-present?
|
2006-02-23 19:01:12 -05:00
|
|
|
dup indirect-base { ESP RSP } memq?
|
|
|
|
over indirect-index rot indirect-scale or or ;
|
|
|
|
|
|
|
|
M: register sib-present? drop f ;
|
|
|
|
|
|
|
|
GENERIC: r/m
|
|
|
|
|
2006-08-15 03:01:24 -04:00
|
|
|
M: indirect r/m
|
2006-02-24 02:26:08 -05:00
|
|
|
dup sib-present?
|
|
|
|
[ drop ESP reg-code ] [ indirect-base* ] if ;
|
2006-02-23 19:01:12 -05:00
|
|
|
|
2006-08-15 03:01:24 -04:00
|
|
|
M: register r/m reg-code ;
|
2006-02-23 19:01:12 -05:00
|
|
|
|
|
|
|
: byte? -128 127 between? ;
|
|
|
|
|
|
|
|
GENERIC: modifier
|
|
|
|
|
|
|
|
M: indirect modifier
|
|
|
|
dup indirect-base [
|
|
|
|
indirect-displacement BIN: 10 BIN: 00 ?
|
|
|
|
] [
|
|
|
|
drop BIN: 00
|
|
|
|
] if ;
|
|
|
|
|
2006-02-23 20:22:18 -05:00
|
|
|
M: register modifier drop BIN: 11 ;
|
2006-02-23 19:01:12 -05:00
|
|
|
|
|
|
|
: mod-r/m ( reg# indirect -- byte )
|
2006-02-24 02:26:08 -05:00
|
|
|
dup modifier 6 shift rot 3 shift rot r/m bitor bitor ;
|
2006-02-23 19:01:12 -05:00
|
|
|
|
|
|
|
: sib ( indirect -- byte )
|
|
|
|
dup sib-present? [
|
|
|
|
dup indirect-base*
|
|
|
|
over indirect-index* 3 shift bitor
|
2006-02-23 20:22:18 -05:00
|
|
|
swap indirect-scale* 6 shift bitor
|
2006-02-23 19:01:12 -05:00
|
|
|
] [
|
|
|
|
drop f
|
|
|
|
] if ;
|
|
|
|
|
|
|
|
GENERIC: displacement
|
|
|
|
|
|
|
|
M: indirect displacement indirect-displacement ;
|
|
|
|
|
|
|
|
M: register displacement drop f ;
|
|
|
|
|
|
|
|
: addressing ( reg# indirect -- )
|
2006-08-08 01:38:32 -04:00
|
|
|
[ mod-r/m , ] keep
|
|
|
|
[ sib [ , ] when* ] keep
|
|
|
|
displacement [ 4, ] when* ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
|
|
|
( Utilities )
|
2006-02-23 19:01:12 -05:00
|
|
|
UNION: operand register indirect ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
2006-07-11 00:48:35 -04:00
|
|
|
: operand-64? ( operand -- ? )
|
|
|
|
dup indirect? [
|
|
|
|
dup indirect-base register-64?
|
|
|
|
swap indirect-index register-64? or
|
|
|
|
] [
|
|
|
|
register-64?
|
|
|
|
] if ;
|
|
|
|
|
|
|
|
: rex.w? ( rex.w reg mod-r/m -- ? )
|
|
|
|
[ operand-64? ] [ operand-64? ] ?if and ;
|
2005-12-02 03:49:25 -05:00
|
|
|
|
2006-03-19 21:24:06 -05:00
|
|
|
: lhs-prefix
|
|
|
|
extended? [ BIN: 00000100 bitor ] when ;
|
|
|
|
|
|
|
|
: rhs-prefix
|
|
|
|
[ extended? [ BIN: 00000001 bitor ] when ] keep
|
|
|
|
dup indirect? [
|
|
|
|
indirect-index extended?
|
|
|
|
[ BIN: 00000010 bitor ] when
|
|
|
|
] [
|
|
|
|
drop
|
|
|
|
] if ;
|
|
|
|
|
2005-12-04 02:30:19 -05:00
|
|
|
: rex-prefix ( reg r/m rex.w -- )
|
2005-12-02 03:49:25 -05:00
|
|
|
#! Compile an AMD64 REX prefix.
|
2005-12-04 02:30:19 -05:00
|
|
|
pick pick rex.w? BIN: 01001000 BIN: 01000000 ?
|
2006-03-19 21:24:06 -05:00
|
|
|
swap lhs-prefix swap rhs-prefix
|
2006-08-08 01:38:32 -04:00
|
|
|
dup BIN: 01000000 = [ drop ] [ , ] if ;
|
2005-12-02 03:49:25 -05:00
|
|
|
|
2006-01-31 21:31:53 -05:00
|
|
|
: 16-prefix ( reg r/m -- )
|
2006-08-08 01:38:32 -04:00
|
|
|
[ register-16? ] 2apply or [ HEX: 66 , ] when ;
|
2006-01-31 21:31:53 -05:00
|
|
|
|
|
|
|
: prefix ( reg r/m rex.w -- ) pick pick 16-prefix rex-prefix ;
|
|
|
|
|
|
|
|
: prefix-1 ( reg rex.w -- ) f swap prefix ;
|
2005-12-04 02:30:19 -05:00
|
|
|
|
|
|
|
: short-operand ( reg rex.w n -- )
|
2005-01-08 16:43:18 -05:00
|
|
|
#! Some instructions encode their single operand as part of
|
|
|
|
#! the opcode.
|
2006-08-08 01:38:32 -04:00
|
|
|
>r dupd prefix-1 reg-code r> + , ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
2005-12-04 02:30:19 -05:00
|
|
|
: 1-operand ( op reg rex.w opcode -- )
|
|
|
|
#! The 'reg' is not really a register, but a value for the
|
|
|
|
#! 'reg' field of the mod-r/m byte.
|
2006-08-08 01:38:32 -04:00
|
|
|
>r >r over r> prefix-1 r> , swap addressing ;
|
2006-02-23 19:01:12 -05:00
|
|
|
|
|
|
|
: immediate-1 ( imm dst reg rex.w opcode -- )
|
2006-08-08 01:38:32 -04:00
|
|
|
1-operand , ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
2005-12-04 02:30:19 -05:00
|
|
|
: immediate-1/4 ( imm dst reg rex.w opcode -- )
|
2005-01-08 16:43:18 -05:00
|
|
|
#! If imm is a byte, compile the opcode and the byte.
|
|
|
|
#! Otherwise, set the 32-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.
|
2005-12-04 02:30:19 -05:00
|
|
|
>r >r pick byte? [
|
|
|
|
r> r> BIN: 10 bitor immediate-1
|
2005-01-08 16:43:18 -05:00
|
|
|
] [
|
2006-08-08 01:38:32 -04:00
|
|
|
r> r> 1-operand 4,
|
2005-09-24 15:21:17 -04:00
|
|
|
] if ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
|
|
|
: 2-operand ( dst src op -- )
|
|
|
|
#! Sets the opcode's direction bit. It is set if the
|
|
|
|
#! destination is a direct register operand.
|
|
|
|
pick register? [ BIN: 10 bitor swapd ] when
|
2006-08-08 01:38:32 -04:00
|
|
|
>r 2dup t prefix r> , reg-code swap addressing ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
2005-12-07 00:14:24 -05:00
|
|
|
PREDICATE: word callable register? not ;
|
|
|
|
|
2005-01-08 16:43:18 -05:00
|
|
|
( Moving stuff )
|
|
|
|
GENERIC: PUSH ( op -- )
|
2005-12-04 02:30:19 -05:00
|
|
|
M: register PUSH f HEX: 50 short-operand ;
|
2006-08-08 01:38:32 -04:00
|
|
|
M: integer PUSH HEX: 68 , 4, ;
|
|
|
|
M: callable PUSH 0 PUSH rel-absolute rel-word ;
|
2006-08-09 18:25:11 -04:00
|
|
|
M: label PUSH 0 PUSH rel-absolute rel-label ;
|
2005-12-04 02:30:19 -05:00
|
|
|
M: operand PUSH BIN: 110 f HEX: ff 1-operand ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
|
|
|
GENERIC: POP ( op -- )
|
2005-12-04 02:30:19 -05:00
|
|
|
M: register POP f HEX: 58 short-operand ;
|
|
|
|
M: operand POP BIN: 000 f HEX: 8f 1-operand ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
|
|
|
! MOV where the src is immediate.
|
|
|
|
GENERIC: (MOV-I) ( src dst -- )
|
2006-08-08 01:38:32 -04:00
|
|
|
M: register (MOV-I) t HEX: b8 short-operand cell, ;
|
|
|
|
M: operand (MOV-I) BIN: 000 t HEX: c7 1-operand 4, ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
|
|
|
GENERIC: MOV ( dst src -- )
|
|
|
|
M: integer MOV swap (MOV-I) ;
|
2006-08-08 01:38:32 -04:00
|
|
|
M: callable MOV 0 rot (MOV-I) rel-absolute-cell rel-word ;
|
2006-08-09 18:25:11 -04:00
|
|
|
M: label MOV 0 rot (MOV-I) rel-absolute-cell rel-label ;
|
2005-01-08 16:43:18 -05:00
|
|
|
M: operand MOV HEX: 89 2-operand ;
|
|
|
|
|
|
|
|
( Control flow )
|
|
|
|
GENERIC: JMP ( op -- )
|
2006-08-09 18:25:11 -04:00
|
|
|
: (JMP) HEX: e9 , 0 4, rel-relative ;
|
|
|
|
M: callable JMP (JMP) rel-word ;
|
|
|
|
M: label JMP (JMP) rel-label ;
|
2005-12-04 02:30:19 -05:00
|
|
|
M: operand JMP BIN: 100 t HEX: ff 1-operand ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
|
|
|
GENERIC: CALL ( op -- )
|
2006-08-09 18:25:11 -04:00
|
|
|
: (CALL) HEX: e8 , 0 4, rel-relative ;
|
|
|
|
M: callable CALL (CALL) rel-word ;
|
|
|
|
M: label CALL (CALL) rel-label ;
|
2005-12-04 02:30:19 -05:00
|
|
|
M: operand CALL BIN: 010 t HEX: ff 1-operand ;
|
2005-05-07 22:39:00 -04:00
|
|
|
|
2006-05-05 23:06:08 -04:00
|
|
|
G: JUMPcc ( addr opcode -- ) 1 standard-combination ;
|
2006-08-09 18:25:11 -04:00
|
|
|
: (JUMPcc) HEX: 0f , , 0 4, rel-relative ;
|
2006-08-15 03:01:24 -04:00
|
|
|
M: callable JUMPcc (JUMPcc) rel-word ;
|
|
|
|
M: label JUMPcc (JUMPcc) rel-label ;
|
2006-05-05 23:06:08 -04:00
|
|
|
|
|
|
|
: JO HEX: 80 JUMPcc ;
|
|
|
|
: JNO HEX: 81 JUMPcc ;
|
|
|
|
: JB HEX: 82 JUMPcc ;
|
|
|
|
: JAE HEX: 83 JUMPcc ;
|
|
|
|
: JE HEX: 84 JUMPcc ; ! aka JZ
|
|
|
|
: JNE HEX: 85 JUMPcc ;
|
|
|
|
: JBE HEX: 86 JUMPcc ;
|
|
|
|
: JA HEX: 87 JUMPcc ;
|
|
|
|
: JS HEX: 88 JUMPcc ;
|
|
|
|
: JNS HEX: 89 JUMPcc ;
|
|
|
|
: JP HEX: 8a JUMPcc ;
|
|
|
|
: JNP HEX: 8b JUMPcc ;
|
|
|
|
: JL HEX: 8c JUMPcc ;
|
|
|
|
: JGE HEX: 8d JUMPcc ;
|
|
|
|
: JLE HEX: 8e JUMPcc ;
|
|
|
|
: JG HEX: 8f JUMPcc ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
2006-08-08 01:38:32 -04:00
|
|
|
: RET ( -- ) HEX: c3 , ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
|
|
|
( Arithmetic )
|
|
|
|
|
|
|
|
GENERIC: ADD ( dst src -- )
|
2005-12-04 02:30:19 -05:00
|
|
|
M: integer ADD swap BIN: 000 t HEX: 81 immediate-1/4 ;
|
2005-05-06 19:49:07 -04:00
|
|
|
M: operand ADD OCT: 001 2-operand ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
2005-05-06 19:49:07 -04:00
|
|
|
GENERIC: OR ( dst src -- )
|
2005-12-04 02:30:19 -05:00
|
|
|
M: integer OR swap BIN: 001 t HEX: 81 immediate-1/4 ;
|
2005-05-06 19:49:07 -04:00
|
|
|
M: operand OR OCT: 011 2-operand ;
|
|
|
|
|
|
|
|
GENERIC: ADC ( dst src -- )
|
2005-12-04 02:30:19 -05:00
|
|
|
M: integer ADC swap BIN: 010 t HEX: 81 immediate-1/4 ;
|
2005-05-06 19:49:07 -04:00
|
|
|
M: operand ADC OCT: 021 2-operand ;
|
|
|
|
|
|
|
|
GENERIC: SBB ( dst src -- )
|
2005-12-04 02:30:19 -05:00
|
|
|
M: integer SBB swap BIN: 011 t HEX: 81 immediate-1/4 ;
|
2005-05-06 19:49:07 -04:00
|
|
|
M: operand SBB OCT: 031 2-operand ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
2005-01-16 17:58:28 -05:00
|
|
|
GENERIC: AND ( dst src -- )
|
2005-12-04 02:30:19 -05:00
|
|
|
M: integer AND swap BIN: 100 t HEX: 81 immediate-1/4 ;
|
2005-05-06 19:49:07 -04:00
|
|
|
M: operand AND OCT: 041 2-operand ;
|
|
|
|
|
|
|
|
GENERIC: SUB ( dst src -- )
|
2005-12-04 02:30:19 -05:00
|
|
|
M: integer SUB swap BIN: 101 t HEX: 81 immediate-1/4 ;
|
2005-05-06 19:49:07 -04:00
|
|
|
M: operand SUB OCT: 051 2-operand ;
|
|
|
|
|
|
|
|
GENERIC: XOR ( dst src -- )
|
2005-12-04 02:30:19 -05:00
|
|
|
M: integer XOR swap BIN: 110 t HEX: 81 immediate-1/4 ;
|
2005-05-06 19:49:07 -04:00
|
|
|
M: operand XOR OCT: 061 2-operand ;
|
|
|
|
|
|
|
|
GENERIC: CMP ( dst src -- )
|
2005-12-04 02:30:19 -05:00
|
|
|
M: integer CMP swap BIN: 111 t HEX: 81 immediate-1/4 ;
|
2005-05-06 19:49:07 -04:00
|
|
|
M: operand CMP OCT: 071 2-operand ;
|
2005-01-16 17:58:28 -05:00
|
|
|
|
2005-12-04 02:30:19 -05:00
|
|
|
: NOT ( dst -- ) BIN: 010 t HEX: f7 1-operand ;
|
|
|
|
: NEG ( dst -- ) BIN: 011 t HEX: f7 1-operand ;
|
|
|
|
: MUL ( dst -- ) BIN: 100 t HEX: f7 1-operand ;
|
|
|
|
: IMUL ( src -- ) BIN: 101 t HEX: f7 1-operand ;
|
|
|
|
: DIV ( dst -- ) BIN: 110 t HEX: f7 1-operand ;
|
|
|
|
: IDIV ( src -- ) BIN: 111 t HEX: f7 1-operand ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
2006-07-05 23:30:56 -04:00
|
|
|
GENERIC: IMUL2 ( dst src -- )
|
|
|
|
M: integer IMUL2 swap dup reg-code t HEX: 69 immediate-1/4 ;
|
|
|
|
|
2006-08-08 01:38:32 -04:00
|
|
|
: CDQ HEX: 99 , ;
|
|
|
|
: CQO HEX: 48 , CDQ ;
|
2005-01-08 16:43:18 -05:00
|
|
|
|
2005-12-04 02:30:19 -05:00
|
|
|
: ROL ( dst n -- ) swap BIN: 000 t HEX: c1 immediate-1 ;
|
|
|
|
: ROR ( dst n -- ) swap BIN: 001 t HEX: c1 immediate-1 ;
|
|
|
|
: RCL ( dst n -- ) swap BIN: 010 t HEX: c1 immediate-1 ;
|
|
|
|
: RCR ( dst n -- ) swap BIN: 011 t HEX: c1 immediate-1 ;
|
|
|
|
: SHL ( dst n -- ) swap BIN: 100 t HEX: c1 immediate-1 ;
|
|
|
|
: SHR ( dst n -- ) swap BIN: 101 t HEX: c1 immediate-1 ;
|
|
|
|
: SAR ( dst n -- ) swap BIN: 111 t HEX: c1 immediate-1 ;
|
2005-05-04 22:34:55 -04:00
|
|
|
|
|
|
|
( x87 Floating Point Unit )
|
|
|
|
|
2006-02-18 18:39:23 -05:00
|
|
|
: FSTPS ( operand -- ) BIN: 011 f HEX: d9 1-operand ;
|
|
|
|
: FSTPL ( operand -- ) BIN: 011 f HEX: dd 1-operand ;
|
2006-01-24 20:20:20 -05:00
|
|
|
|
2006-02-18 18:39:23 -05:00
|
|
|
: FLDS ( operand -- ) BIN: 000 f HEX: d9 1-operand ;
|
|
|
|
: FLDL ( operand -- ) BIN: 000 f HEX: dd 1-operand ;
|
2006-02-15 00:20:35 -05:00
|
|
|
|
2006-01-24 20:20:20 -05:00
|
|
|
( SSE multimedia instructions )
|
|
|
|
|
2006-01-25 01:18:12 -05:00
|
|
|
: 2-operand-sse ( dst src op1 op2 -- )
|
2006-05-04 16:05:58 -04:00
|
|
|
#! We swap the operands here to make everything consistent
|
|
|
|
#! with the integer instructions.
|
2006-08-08 01:38:32 -04:00
|
|
|
swap , pick register-128? [ swapd ] [ 1 bitor ] if
|
|
|
|
>r 2dup t prefix HEX: 0f , r>
|
|
|
|
, reg-code swap addressing ;
|
2006-01-25 01:18:12 -05:00
|
|
|
|
2006-05-04 16:05:58 -04:00
|
|
|
: MOVSS ( dest src -- ) HEX: f3 HEX: 10 2-operand-sse ;
|
|
|
|
: MOVSD ( dest src -- ) HEX: f2 HEX: 10 2-operand-sse ;
|
|
|
|
: ADDSD ( dest src -- ) HEX: f2 HEX: 58 2-operand-sse ;
|
|
|
|
: MULSD ( dest src -- ) HEX: f2 HEX: 59 2-operand-sse ;
|
|
|
|
: SUBSD ( dest src -- ) HEX: f2 HEX: 5c 2-operand-sse ;
|
|
|
|
: DIVSD ( dest src -- ) HEX: f2 HEX: 5e 2-operand-sse ;
|
|
|
|
: SQRTSD ( dest src -- ) HEX: f2 HEX: 51 2-operand-sse ;
|
|
|
|
: UCOMISD ( dest src -- ) HEX: 66 HEX: 2e 2-operand-sse ;
|
|
|
|
: COMISD ( dest src -- ) HEX: 66 HEX: 2f 2-operand-sse ;
|
|
|
|
: CVTSI2SD ( dest src -- ) HEX: f2 HEX: 2a 2-operand-sse ;
|
|
|
|
: CVTSD2SI ( dest src -- ) HEX: f2 HEX: 2d 2-operand-sse ;
|