Compare commits

...

2 Commits

Author SHA1 Message Date
Ed_
8a974e9c89 editor config 2024-11-24 23:13:33 -05:00
Ed_
dbfd94ea40 add flat assembler toolchain 2024-11-24 23:13:28 -05:00
303 changed files with 145630 additions and 0 deletions

31
.editorconfig Normal file
View File

@ -0,0 +1,31 @@
root = true
[*.asm]
indent_style = tab
indent_size = 2
[*.refactor]
indent_style = space
indent_size = 4
[*.md]
indent_style = space
indent_size = 4
[*.{h, c, hpp, cpp}]
indent_style = tab
indent_size = 4
[*.{ps1, psm1}]
indent_style = tab
indent_size = 4
[*.odin]
indent_style = tab
indent_size = 2
charset = utf-8
[*.{natvis, natstepfilter}]
indent_style = tab
indent_size = 4

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,861 @@
; This is a very basic implementation of 8051 instruction set, which treats
; all types of addresses as plain numeric values and therefore is not able to
; detect whether symbol has been used in context it was not intended for.
element R
repeat 8 i:0
element R#i? : R + i
end repeat
element @
element @R0? : @
element @R1? : @ + 1
macro AJMP? addr
local value
value = +addr
if value and not 7FFh = ($+2) and not 7FFh
db 01h + value shr 3 and 11100000b,value and 0FFh
else
err "address out of range"
end if
end macro
macro ACALL? addr
local value
value = +addr
if value and not 7FFh = ($+2) and not 7FFh
db 11h + value shr 3 and 11100000b,value and 0FFh
else
err "address out of range"
end if
end macro
macro LCALL? addr
local value
value = +addr
db 12h,value shr 8,value and 0FFh
end macro
macro LJMP? addr
local value
value = +addr
db 02h,value shr 8,value and 0FFh
end macro
macro SJMP? addr
local offset
offset = -($+2)+addr
if offset>=-80h & offset<80h
db 80h,offset
else
err "relative jump out of range"
end if
end macro
macro CALL? addr
local value
value = +addr
if value and not 7FFh = ($+2) and not 7FFh
db 11h + value shr 3 and 11100000b
else
db 12h,value shr 8
end if
db value and 0FFh
end macro
macro JMP? addr
local value,offset
match =@A? + =DPTR?, addr
db 73h
else
value = +addr
offset = value-($+2)
if offset>=-80h & offset<80h
db 80h,offset
else
if value and not 7FFh = ($+2) and not 7FFh
db 01h + value shr 3 and 11100000b
else
db 02h,value shr 8
end if
db value and 0FFh
end if
end match
end macro
macro CJNE? operand1,operand2,addr
local value,offset
offset = -($+3)+addr
if offset>=-80h & offset<80h
match =A?, operand1
match #data, operand2
value = +data
db 0B4h,value
else
value = +operand2
db 0B5h,value
end match
else match #data,operand2
value = +operand1
if value eq value element 1
if value metadata 1 relativeto @
db 0B6h + value metadata 1 - @
else if value metadata 1 relativeto R
db 0B8h + value metadata 1 - R
else
err "invalid operand"
end if
db +data
else
err "invalid operand"
end if
else
err 'invalid operand'
end match
db offset
else
err "relative jump out of range"
end if
end macro
macro DJNZ? operand,addr
local value,offset
value = +operand
if value relativeto 0
offset = -($+3)+addr
if offset>=-80h & offset<80h
db 0D5h,value,offset
else
err "relative jump out of range"
end if
else if value eq value element 1 & value metadata 1 relativeto R
offset = -($+2)+addr
if offset>=-80h & offset<80h
db 0D8h + value metadata 1 - R,offset
else
err "relative jump out of range"
end if
else
err "invalid operand"
end if
end macro
macro JBC? operand,addr
local offset
offset = -($+3)+addr
if offset>=-80h & offset<80h
db 10h,operand,offset
else
err "relative jump out of range"
end if
end macro
macro JB? operand,addr
local offset
offset = -($+3)+addr
if offset>=-80h & offset<80h
db 20h,operand,offset
else
err "relative jump out of range"
end if
end macro
macro JNB? operand,addr
local offset
offset = -($+3)+addr
if offset>=-80h & offset<80h
db 30h,operand,offset
else
err "relative jump out of range"
end if
end macro
macro JC? addr
local offset
offset = -($+2)+addr
if offset>=-80h & offset<80h
db 40h,offset
else
err "relative jump out of range"
end if
end macro
macro JNC? addr
local offset
offset = -($+2)+addr
if offset>=-80h & offset<80h
db 50h,offset
else
err "relative jump out of range"
end if
end macro
macro JZ? addr
local offset
offset = -($+2)+addr
if offset>=-80h & offset<80h
db 60h,offset
else
err "relative jump out of range"
end if
end macro
macro JNZ? addr
local offset
offset = -($+2)+addr
if offset>=-80h & offset<80h
db 70h,offset
else
err "relative jump out of range"
end if
end macro
macro ADD? accu,operand
local value
match =A?, accu
match #data, operand
value = +data
db 24h,value
else
value = +operand
if value relativeto 0
db 25h,value
else if value eq value element 1
if value metadata 1 relativeto @
db 26h + value metadata 1 - @
else if value metadata 1 relativeto R
db 28h + value metadata 1 - R
else
err "invalid operand"
end if
else
err "invalid operand"
end if
end match
else
err 'invalid operand'
end match
end macro
macro ADDC? accu,operand
local value
match =A?, accu
match #data, operand
value = +data
db 34h,value
else
value = +operand
if value relativeto 0
db 35h,value
else if value eq value element 1
if value metadata 1 relativeto @
db 36h + value metadata 1 - @
else if value metadata 1 relativeto R
db 38h + value metadata 1 - R
else
err "invalid operand"
end if
else
err "invalid operand"
end if
end match
else
err 'invalid operand'
end match
end macro
macro SUBB? accu,operand
local value
match =A?, accu
match #data, operand
value = +data
db 94h,value
else
value = +operand
if value relativeto 0
db 95h,value
else if value eq value element 1
if value metadata 1 relativeto @
db 96h + value metadata 1 - @
else if value metadata 1 relativeto R
db 98h + value metadata 1 - R
else
err "invalid operand"
end if
else
err "invalid operand"
end if
end match
else
err 'invalid operand'
end match
end macro
macro ANL? dest,src
local value,data_value
match =A?, dest
match #data, src
value = +data
db 54h,value
else
value = +src
if value relativeto 0
db 55h,value
else if value eq value element 1
if value metadata 1 relativeto @
db 56h + value metadata 1 - @
else if value metadata 1 relativeto R
db 58h + value metadata 1 - R
else
err "invalid operand"
end if
else
err "invalid operand"
end if
end match
else match =C?, dest
match /addr,src
db 0B0h,addr
else
db 82h,src
end match
else
match =A?, src
value = +dest
db 52h,value
else match #data, src
value = +dest
data_value = +data
db 53h,value,data_value
else
err 'invalid operand'
end match
end match
end macro
macro ORL? dest,src
local value,data_value
match =A?, dest
match #data, src
value = +data
db 44h,value
else
value = +src
if value relativeto 0
db 45h,value
else if value eq value element 1
if value metadata 1 relativeto @
db 46h + value metadata 1 - @
else if value metadata 1 relativeto R
db 48h + value metadata 1 - R
else
err "invalid operand"
end if
else
err "invalid operand"
end if
end match
else match =C?, dest
match /addr,src
db 0A0h,addr
else
db 72h,src
end match
else
match =A?, src
value = +dest
db 42h,value
else match #data, src
value = +dest
data_value = +data
db 43h,value,data_value
else
err 'invalid operand'
end match
end match
end macro
macro XRL? dest,src
local value,data_value
match =A?, dest
match #data, src
value = +data
db 64h,value
else
value = +src
if value relativeto 0
db 65h,value
else if value eq value element 1
if value metadata 1 relativeto @
db 66h + value metadata 1 - @
else if value metadata 1 relativeto R
db 68h + value metadata 1 - R
else
err "invalid operand"
end if
else
err "invalid operand"
end if
end match
else
match =A?, src
value = +dest
db 62h,value
else match #data, src
value = +dest
data_value = +data
db 63h,value,data_value
else
err 'invalid operand'
end match
end match
end macro
macro CLR? operand
match =A?, operand
db 0E4h
else match =C?, operand
db 0C3h
else
db 0C2h,operand
end match
end macro
macro CPL? operand
match =A?, operand
db 0F4h
else match =C?, operand
db 0B3h
else
db 0B2h,operand
end match
end macro
macro SETB? operand
match =C?, operand
db 0D3h
else
db 0D2h,operand
end match
end macro
macro DEC? operand
local value
match =A?, operand
db 14h
else
value = +operand
if value relativeto 0
db 15h,value
else if value eq value element 1
if value metadata 1 relativeto @
db 16h + value metadata 1 - @
else if value metadata 1 relativeto R
db 18h + value metadata 1 - R
else
err "invalid operand"
end if
else
err "invalid operand"
end if
end match
end macro
macro INC? operand
local value
match =A?, operand
db 04h
else match =DPTR?, operand
db 0A3h
else
value = +operand
if value relativeto 0
db 05h,value
else if value eq value element 1
if value metadata 1 relativeto @
db 06h + value metadata 1 - @
else if value metadata 1 relativeto R
db 08h + value metadata 1 - R
else
err "invalid operand"
end if
else
err "invalid operand"
end if
end match
end macro
macro MOV? dest,src
local value,data_value
match =A?, dest
match #data, src
value = +data
db 74h,value
else
value = +src
if value relativeto 0
db 0E5h,value
else if value eq value element 1
if value metadata 1 relativeto @
db 0E6h + value metadata 1 - @
else if value metadata 1 relativeto R
db 0E8h + value metadata 1 - R
else
err "invalid operand"
end if
else
err "invalid operand"
end if
end match
else match =C?, dest
db 0A2h,src
else match =C?, src
db 92h,dest
else match =DPTR?, dest
value = src
db 90h
if value eqtype ''
dw +src
else
db value shr 8,value and 0FFh
end if
else
value = +dest
if value relativeto 0
match =A?, src
db 0F5h,value
else match #data, src
data_value = +data
db 75h,value,data_value
else
@value2 = +src
if @value2 relativeto 0
db 85h,@value2,value
else if @value2 eq @value2 element 1
if @value2 metadata 1 relativeto @
db 86h + @value2 metadata 1 - @,value
else if @value2 metadata 1 relativeto R
db 88h + @value2 metadata 1 - R,value
end if
else if
err "invalid operand"
end if
end match
else if value eq value element 1
if value metadata 1 relativeto @
match =A?, src
db 0F6h + value metadata 1 - @
else match #data, src
data_value = +data
db 76h + value metadata 1 - @,data_value
else
data_value = +src
db 0A6h + value metadata 1 - @,data_value
end match
else if value metadata 1 relativeto R
match =A?, src
db 0F8h + value metadata 1 - R
else match #data, src
data_value = +data
db 78h + value metadata 1 - R,data_value
else
data_value = +src
db 0A8h + value metadata 1 - R,data_value
end match
else
err "invalid operand"
end if
else
err "invalid operand"
end if
end match
end macro
macro MOVC? operands&
match =A?=, =@A? + =DPTR?, operands
db 93h
else match =A?=, =@A? + =PC?, operands
db 83h
else
err "invalid operand"
end match
end macro
macro MOVX? dest,src
local value
match =A?, dest
match =@DPTR?, src
db 0E0h
else
value = +src
if value eq value element 1 & value metadata 1 relativeto @
db 0E2h + value metadata 1 - @
else
err "invalid operand"
end if
end match
else match =A?, src
match =@DPTR?, dest
db 0F0h
else
value = +dest
if value eq value element 1 & value metadata 1 relativeto @
db 0F2h + value metadata 1 - @
else
err "invalid operand"
end if
end match
else
err "invalid operand"
end match
end macro
macro SWAP? operand
match =A?, operand
db 0C4h
else
err 'invalid operand'
end match
end macro
macro DA? operand
match =A?, operand
db 0D4h
else
err 'invalid operand'
end match
end macro
macro RR? operand
match =A?, operand
db 03h
else
err 'invalid operand'
end match
end macro
macro RRC? operand
match =A?, operand
db 13h
else
err 'invalid operand'
end match
end macro
macro RL? operand
match =A?, operand
db 23h
else
err 'invalid operand'
end match
end macro
macro RLC? operand
match =A?, operand
db 33h
else
err 'invalid operand'
end match
end macro
macro DIV? operand
match =AB?, operand
db 84h
else
err "invalid operand"
end match
end macro
macro MUL? operand
match =AB?, operand
db 0A4h
else
err "invalid operand"
end match
end macro
macro NOP?
db 0
end macro
macro POP? addr
local value
value = +addr
db 0D0h,value
end macro
macro PUSH? addr
local value
value = +addr
db 0C0h,value
end macro
macro RET?
db 22h
end macro
macro RETI?
db 32h
end macro
macro XCH? accu,operand
local value
match =A?, accu
value = +operand
if value relativeto 0
db 0C5h,value
else if value eq value element 1
if value metadata 1 relativeto @
db 0C6h + value metadata 1 - @
else if value metadata 1 relativeto R
db 0C8h + value metadata 1 - R
else
err "invalid operand"
end if
else
err "invalid operand"
end if
else
err 'invalid operand'
end match
end macro
macro XCHD? accu,src
local value
match =A?, accu
value = +src
if value eq value element 1 & value metadata 1 relativeto @
db 0D6h + value metadata 1 - @
else
err "invalid operand"
end if
else
err "invalid operand"
end match
end macro
struc EQU? value
. = value
end struc
DSEG?.$ = 0
DSEG?.open = 0
macro DSEG? @:at DSEG?.$
if ~ DSEG?.open
virtual @
DSEG?.open = 1
else
match =AT? addr, @
org addr
else
err 'invalid argument'
end match
end if
end macro
macro CSEG? @
if DSEG?.open
DSEG?.$ = $
end virtual
DSEG?.open = 0
end if
match =AT? addr, @
org addr
else match any, @
err 'invalid argument'
end match
end macro
macro bitslabel definition
match name =at? address, definition
label name at address
repeat 8, i:0
label name.i at address+i
end repeat
else
err 'syntax error'
end match
end macro
; Data addresses:
bitslabel P0 at 080h
bitslabel SP at 081h
bitslabel DPL at 082h
bitslabel DPH at 083h
bitslabel PCON at 087h
bitslabel TCON at 088h
bitslabel TMOD at 089h
bitslabel TL0 at 08Ah
bitslabel TL1 at 08Bh
bitslabel TH0 at 08Ch
bitslabel TH1 at 08Dh
bitslabel P1 at 090h
bitslabel SCON at 098h
bitslabel SBUF at 099h
bitslabel P2 at 0A0h
bitslabel IE at 0A8h
bitslabel P3 at 0B0h
bitslabel IP at 0B8h
bitslabel PSW at 0D0h
bitslabel ACC at 0E0h
bitslabel B at 0F0h
; Bit addresses:
label IT0 at 088h
label IE0 at 089h
label IT1 at 08Ah
label IE1 at 08Bh
label TR0 at 08Ch
label TF0 at 08Dh
label TR1 at 08Eh
label TF1 at 08Fh
label RI at 098h
label TI at 099h
label RB8 at 09Ah
label TB8 at 09Bh
label REN at 09Ch
label SM2 at 09Dh
label SM1 at 09Eh
label SM0 at 09Fh
label EX0 at 0A8h
label ET0 at 0A9h
label EX1 at 0AAh
label ET1 at 0ABh
label ES at 0ACh
label EA at 0AFh
label RXD at 0B0h
label TXD at 0B1h
label INT0 at 0B2h
label INT1 at 0B3h
label T0 at 0B4h
label T1 at 0B5h
label WR at 0B6h
label RD at 0B7h
label PX0 at 0B8h
label PT0 at 0B9h
label PX1 at 0BAh
label PT1 at 0BBh
label PS at 0BCh
label P at 0D0h
label OV at 0D2h
label RS0 at 0D3h
label RS1 at 0D4h
label F0 at 0D5h
label AC at 0D6h
label CY at 0D7h
; Code addresses:
label RESET at 000h
label EXTI0 at 003h
label TIMER0 at 00Bh
label EXTI1 at 013h
label TIMER1 at 01Bh
label SINT at 023h

View File

@ -0,0 +1,75 @@
define HEX
format binary as 'hex'
virtual at 0
HEX.digits:: db '0123456789ABCDEF'
end virtual
macro HEX.byte value
HEX.checksum = (HEX.checksum + (value)) and 0FFh
local digit
load digit:byte from HEX.digits:(value) shr 4
db digit
load digit:byte from HEX.digits:(value) and 0Fh
db digit
end macro
macro HEX.line length,address,type,value
HEX.checksum = 0
db ':'
HEX.byte length
HEX.byte (address) shr 8
HEX.byte (address) and 0FFh
HEX.byte type
HEX.data = value
repeat length
HEX.byte HEX.data and 0FFh
HEX.data = HEX.data shr 8
end repeat
HEX.data = (-HEX.checksum) and 0FFh
HEX.byte HEX.data
db 13,10
end macro
macro HEX.seg address:0
virtual at address
end macro
macro HEX.endseg
local code,address,high,size,bytes
code:: address = $$
size = $-$$
end virtual
high = 0
while size
if address shr 16 <> high
high = address shr 16
HEX.line 2,0,4,high bswap 2
end if
if size>10h
load bytes:10h from code:address
HEX.line 10h,address and 0FFFFh,0,bytes
address = address + 10h
size = size - 10h
else
load bytes:size from code:address
HEX.line size,address and 0FFFFh,0,bytes
break
end if
end while
end macro
macro ORG? address
if $ <> address
HEX.endseg
HEX.seg address
end if
end macro
HEX.seg
postpone
HEX.endseg
HEX.line 0,0,1,0
end postpone

View File

@ -0,0 +1,46 @@
; This simple example reads data from external device through P2
; and outputs it inverted through P1.
include 'hex.inc'
include '8051.inc'
ORG 0
JMP setup
ORG 3
JMP ext0_interrupt
ORG 0Bh
JMP timer0_interrupt
ORG 30h
setup:
SETB EX0
SETB IT0
CLR P0.7
MOV TH0,#-40
MOV TL0,#-40
MOV TMOD,#2
SETB TR0
SETB ET0
SETB EA
JMP $
timer0_interrupt:
CLR P3.6
SETB P3.6
RETI
ext0_interrupt:
CLR P3.7
MOV A,P2
CPL A
MOV P1,A
SETB P3.7
RETI

View File

@ -0,0 +1 @@
fasmg invert.asm invert.hex

View File

@ -0,0 +1,903 @@
element R
repeat 32 i:0
element R#i? : R + i
end repeat
XH? = R27
XL? = R26
YH? = R29
YL? = R28
ZH? = R31
ZL? = R30
element X
element Y
element Z
iterate <instr,opcode>, ADC,000111b, ADD,000011b, AND, 001000b, EOR, 001001b, CP,000101b, CPC,000001b, CPSE,000100b, MOV,001011b, MUL,100111b, OR,001010b, SBC,000010b, SUB,000110b
macro instr? Rd,Rr
local value,d,r
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
value = +Rr
if value metadata 1 relativeto R & value eq value element 1
r = value metadata 1 - R
dw r and 1111b + d shl 4 + (r shr 4) shl 9 + opcode shl 10
else
err 'invalid operand'
end if
else
err 'invalid operand'
end if
end macro
end iterate
iterate <instr,opcode>, ADIW,10010110b, SBIW,10010111b
macro instr? RRd,K
local value,d
match Rdh:Rdl,RRd
value = +Rdl
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
value = +Rdh
if value metadata 1 relativeto R & value eq value element 1
if value metadata 1 - R = d + 1
if d = 24 | d = 26 | d = 28 | d = 30
value = +K
if value >= 0 & value <= 63
dw value and 1111b + ((d-24) shr 1) shl 4 + (value shr 4) shl 6 + opcode shl 8
else
err 'immediate value out of range'
end if
else
err 'specified register not allowed for this instruction'
end if
else
err 'invalid operand'
end if
else
err 'invalid operand'
end if
else
err 'invalid operand'
end if
else match Rd,RRd
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
if d = 24 | d = 26 | d = 28 | d = 30
value = +K
if value >= 0 & value <= 63
dw value and 1111b + ((d-24) shr 1) shl 4 + (value shr 4) shl 6 + opcode shl 8
else
err 'immediate value out of range'
end if
else
err 'specified register not allowed for this instruction'
end if
else
err 'invalid operand'
end if
else
err 'invalid operand'
end match
end macro
end iterate
iterate <instr,opcode>, ANDI,0111b, CPI,0011b, LDI,1110b, ORI,0110b, SBCI,0100b, SBR,0110b, SUBI,0101b
macro instr? Rd,K
local value,d
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
if d >= 16
value = +K
if value >= -256 & value <= 255
value = value and 0FFh
dw value and 1111b + (d-16) shl 4 + (value shr 4) shl 8 + opcode shl 12
else
err 'immediate value out of range'
end if
else
err 'specified register not allowed for this instruction'
end if
else
err 'invalid operand'
end if
end macro
end iterate
iterate <instr,opcode>, ASR,0101b, COM,0000b, DEC,1010b, INC,0011b, LSR,0110b, NEG,0001b, ROR,0111b, SWAP,0010b
macro instr? Rd
local value,d
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
dw opcode + d shl 4 + 1001010b shl 9
else
err 'invalid operand'
end if
end macro
end iterate
iterate <instr,opcode>, BCLR,1001'0100'1000'1000b, BSET,1001'0100'0000'1000b
macro instr? s
local value
value = +s
if value >= 0 & value <= 7
dw opcode + value shl 4
else
err 'bit index out of range'
end if
end macro
end iterate
iterate <instr,opcode>, BLD,1111100b, BST,1111101b, SBRC,1111110b, SBRS,1111111b
macro instr? Rd,b
local value,d
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
value = +b
if value >= 0 & value <= 7
dw value + d shl 4 + opcode shl 9
else
err 'bit index out of range'
end if
else
err 'invalid operand'
end if
end macro
end iterate
iterate <instr,opcode>, BRBC,111101b, BRBS,111100b
macro instr? s,k
local index,offset
index = +s
if index >= 0 & index <= 7
offset = -($ shr 1 + 1) + k
if offset >= -64 & offset <= 63
dw index + (offset and 1111111b) shl 3 + opcode shl 10
else
err 'relative jump out of range'
end if
else
err 'bit index out of range'
end if
end macro
end iterate
macro BRCC? k
BRBC 0,k
end macro
macro BRCS? k
BRBS 0,k
end macro
macro BREQ? k
BRBS 1,k
end macro
macro BRGE? k
BRBC 4,k
end macro
macro BRHC? k
BRBC 5,k
end macro
macro BRHS? k
BRBS 5,k
end macro
macro BRID? k
BRBC 7,k
end macro
macro BRIE? k
BRBS 7,k
end macro
macro BRLO? k
BRBS 0,k
end macro
macro BRLT? k
BRBS 4,k
end macro
macro BRMI? k
BRBS 2,k
end macro
macro BRNE? k
BRBC 1,k
end macro
macro BRPL? k
BRBC 2,k
end macro
macro BRSH? k
BRBC 0,k
end macro
macro BRTC? k
BRBC 6,k
end macro
macro BRTS? k
BRBS 6,k
end macro
macro BRVC? k
BRBC 3,k
end macro
macro BRVS? k
BRBS 3,k
end macro
macro CALL? k
local offset
offset = -($ shr 1 + 1) + k
if offset >= -2048 & offset <= 2047
dw offset and (1 shl 12 - 1) + 1101b shl 12
else
offset = +k
if offset >= 0 & offset <= 1 shl 22 - 1
dw (offset shr 16) and 1 + 111b shl 1 + (offset shr 17) shl 4 + 1001010b shl 9
dw offset and (1 shl 16 - 1)
else
err 'value out of range'
end if
end if
end macro
iterate <instr,opcode>, CBI,10011000b, SBI,10011010b, SBIC,10011001b, SBIS,10011011b
macro instr? A,b
local reg,index
reg = +A
if reg >= 0 & reg <= 31
index = +b
if index >= 0 & index <= 7
dw index + reg shl 3 + opcode shl 8
else
err 'bit index out of range'
end if
else
err 'specified register number not allowed'
end if
end macro
end iterate
macro CBR? r,K
ANDI r,$FF-(K)
end macro
macro CLC?
dw 1001'0100'1000'1000b
end macro
macro CLH?
dw 1001'0100'1101'1000b
end macro
macro CLI?
dw 1001'0100'1111'1000b
end macro
macro CLN?
dw 1001'0100'1010'1000b
end macro
macro CLR? r
EOR r,r
end macro
macro CLS?
dw 1001'0100'1100'1000b
end macro
macro CLT?
dw 1001'0100'1110'1000b
end macro
macro CLV?
dw 1001'0100'1011'1000b
end macro
macro CLZ?
dw 1001'0100'1001'1000b
end macro
macro DES? K
local value
value = +K
if value >= 0 & value <= 0x0F
dw 1011b + value shl 4 + 10010100b shl 8
else
err 'value out of range'
end if
end macro
macro EICALL?
dw 1001'0101'0001'1001b
end macro
macro EIJMP?
dw 1001'0100'0001'1001b
end macro
iterate <instr,opcode,opcode2,opcode3>, ELPM,1001'0101'1101'1000b,0110b,0111b, LPM,1001'0101'1100'1000b,0100b,0101b
macro instr? args&
local value,d
match , args
dw opcode
else match Rd=, =Z?, args
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
dw opcode2 + d shl 4 + 1001000b shl 9
else
err 'invalid operand'
end if
else match Rd=, =Z?+, args
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
dw opcode3 + d shl 4 + 1001000b shl 9
else
err 'invalid operand'
end if
else
err 'invalid operand'
end match
end macro
end iterate
iterate <instr,opcode>, FMUL,1100001000b, FMULS,1110000000b, FMULSU,1110001000b
macro instr? Rd,Rr
local value,d,r
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
if d >= 16 & d <= 23
value = +Rr
if value metadata 1 relativeto R & value eq value element 1
r = value metadata 1 - R
if r >= 16 & r <= 23
dw opcode + (r-16) + (d-16) shl 4
else
err 'specified register not allowed for this instruction'
end if
else
err 'invalid operand'
end if
else
err 'specified register not allowed for this instruction'
end if
else
err 'invalid operand'
end if
end macro
end iterate
macro ICALL?
dw 1001'0101'0000'1001b
end macro
macro IJMP?
dw 1001'0100'0000'1001b
end macro
macro IN? Rd,A
local value,d
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
value = +A
if A >= 0 & A <= 63
dw A and 1111b + d shl 4 + (A shr 4) shl 9 + 10110b shl 11
else
err 'address out of range'
end if
else
err 'invalid operand'
end if
end macro
macro JMP? k
local offset
offset = -($ shr 1 + 1) + k
if offset>=-2048 & offset<=2047
dw offset and 111111111111b + 1100b shl 12
else
offset = +k
if offset>=0 & offset<=1 shl 22 - 1
dw (offset shr 16) and 1 + 110b shl 1 + (offset shr 17) shl 4 + 1001010b shl 9
dw offset and (1 shl 16 - 1)
else
err 'value out of range'
end if
end if
end macro
iterate <instr,opcode>, LAC,0110b, LAS,0101b, LAT,0111b, XCH,0100b
macro instr? Rw,Rd
local value,d
match =Z?, Rw
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
dw opcode + d shl 4 + 1001001b shl 9
else
err 'invalid operand'
end if
else
err 'invalid operand'
end match
end macro
end iterate
macro LD? Rd,Rw
local value,d
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
match =X?, Rw
dw 1100b + d shl 4 + 1001000b shl 9
else match =Y?, Rw
dw 1000b + d shl 4 + 1000000b shl 9
else match =Z?, Rw
dw 0000b + d shl 4 + 1000000b shl 9
else match =X?+, Rw
dw 1101b + d shl 4 + 1001000b shl 9
else match =Y?+, Rw
dw 1001b + d shl 4 + 1001000b shl 9
else match =Z?+, Rw
dw 0001b + d shl 4 + 1001000b shl 9
else match -=X?, Rw
dw 1110b + d shl 4 + 1001000b shl 9
else match -=Y?, Rw
dw 1010b + d shl 4 + 1001000b shl 9
else match -=Z?, Rw
dw 0010b + d shl 4 + 1001000b shl 9
else
err 'invalid operand'
end match
else
err 'invalid operand'
end if
end macro
macro LDD? Rd,Rq
local value,d,q
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
value = +Rq
if value relativeto Y
q = value - Y
if q >= 0 & q <= 63
dw q and 111b + 1 shl 3 + d shl 4 + ((q shr 3) and 11b) shl 10 + (q shr 5) shl 13 + 10b shl 14
else
err 'value out of range'
end if
else if value relativeto Z
q = value - Z
if q >= 0 & q <= 63
dw q and 111b + d shl 4 + ((q shr 3) and 11b) shl 10 + (q shr 5) shl 13 + 10b shl 14
else
err 'value out of range'
end if
else
err 'invalid operand'
end if
else
err 'invalid operand'
end if
end macro
macro LDS? Rd,k
local value,d
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
value = +k
if value >= 0 & value <= 65535
dw d shl 4 + 1001000b shl 9
dw value
else
err 'address out of range'
end if
else
err 'invalid operand'
end if
end macro
macro LSL? r
ADD r,r
end macro
macro MOVW? args&
local value,d,r
match Rdh:Rdl=,Rrh:Rrl, args
value = +Rdl
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
value = +Rdh
if value metadata 1 relativeto R & value eq value element 1
if value metadata 1 - R = d + 1 & d and 1 = 0
value = +Rrl
if value metadata 1 relativeto R & value eq value element 1
r = value metadata 1 - R
value = +Rrh
if value metadata 1 relativeto R & value eq value element 1
if value metadata 1 - R = r + 1 & r and 1 = 0
dw r shr 1 + (d shr 1) shl 4 + 1 shl 8
else
err 'invalid operand'
end if
else
err 'invalid operand'
end if
else
err 'invalid operand'
end if
else
err 'invalid operand'
end if
else
err 'invalid operand'
end if
else
err 'invalid operand'
end if
else match Rd=,Rr,args
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
if d and 1 = 0
value = +Rr
if value metadata 1 relativeto R & value eq value element 1
r = value metadata 1 - R
if r and 1 = 0
dw r shr 1 + (d shr 1) shl 4 + 1 shl 8
else
err 'invalid operand'
end if
else
err 'invalid operand'
end if
else
err 'invalid operand'
end if
else
err 'invalid operand'
end if
else
err 'invalid operand'
end match
end macro
iterate <instr,opcode>, MULS,0010b, MULSU,0011b
macro instr? Rd,Rr
local value,d,r
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
if d >= 16 & d <= 31
value = +Rr
if value metadata 1 relativeto R & value eq value element 1
r = value metadata 1 - R
if r >= 16 & r <= 31
dw (r-16) + (d-16) shl 4 + opcode shl 8
else
err 'specified register not allowed for this instruction'
end if
else
err 'invalid operand'
end if
else
err 'specified register not allowed for this instruction'
end if
else
err 'invalid operand'
end if
end macro
end iterate
macro NOP?
dw 0
end macro
macro OUT? A,Rr
local value,r
value = +Rr
if value metadata 1 relativeto R & value eq value element 1
r = value metadata 1 - R
value = +A
if A >= 0 & A <= 63
dw A and 1111b + r shl 4 + (A shr 4) shl 9 + 10111b shl 11
else
err 'address out of range'
end if
else
err 'invalid operand'
end if
end macro
iterate <instr,opcode>, POP,000b, PUSH,001b
macro instr? Rd
local value,d
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
dw 1111b + d shl 4 + opcode shl 9 + 1001b shl 12
else
err 'invalid operand'
end if
end macro
end iterate
iterate <instr,opcode>, RCALL,1101b, RJMP,1100b
macro instr? k
local offset
offset = -($ shr 1 + 1) + k
if offset>=-2048 & offset<=2047
dw offset and 111111111111b + opcode shl 12
else
err 'relative jump out of range'
end if
end macro
end iterate
macro RET?
dw 1001'0101'0000'1000b
end macro
macro RETI?
dw 1001'0101'0001'1000b
end macro
macro ROL? r
ADC r,r
end macro
macro SEC?
dw 1001'0100'0000'1000b
end macro
macro SEH?
dw 1001'0100'0101'1000b
end macro
macro SEI?
dw 1001'0100'0111'1000b
end macro
macro SEN?
dw 1001'0100'0010'1000b
end macro
macro SER? Rd
local value,d
value = +Rd
if value metadata 1 relativeto R & value eq value element 1
d = value metadata 1 - R
if d >= 16
dw 1111b + (d-16) shl 4 + 11101111b shl 8
else
err 'specified register not allowed for this instruction'
end if
else
err 'invalid operand'
end if
end macro
macro SES?
dw 1001'0100'0100'1000b
end macro
macro SET?
dw 1001'0100'0110'1000b
end macro
macro SEV?
dw 1001'0100'0011'1000b
end macro
macro SEZ?
dw 1001'0100'0001'1000b
end macro
macro SLEEP?
dw 1001'0101'1000'1000b
end macro
macro SPM? args
match , args
dw 1001'0101'1110'1000b
else match =Z?+,args
dw 1001'0101'1111'1000b
else
err 'invalid operand'
end match
end macro
macro ST? Rw,Rr
local value,r
value = +Rr
if value metadata 1 relativeto R & value eq value element 1
r = value metadata 1 - R
match =X?, Rw
dw 1100b + r shl 4 + 1001001b shl 9
else match =Y?, Rw
dw 1000b + r shl 4 + 1000001b shl 9
else match =Z?, Rw
dw 0000b + r shl 4 + 1000001b shl 9
else match =X?+, Rw
dw 1101b + r shl 4 + 1001001b shl 9
else match =Y?+, Rw
dw 1001b + r shl 4 + 1001001b shl 9
else match =Z?+, Rw
dw 0001b + r shl 4 + 1001001b shl 9
else match -=X?, Rw
dw 1110b + r shl 4 + 1001001b shl 9
else match -=Y?, Rw
dw 1010b + r shl 4 + 1001001b shl 9
else match -=Z?, Rw
dw 0010b + r shl 4 + 1001001b shl 9
else
err 'invalid operand'
end match
else
err 'invalid operand'
end if
end macro
macro STD? Rq,Rr
local value,r,q
value = +Rr
if value metadata 1 relativeto R & value eq value element 1
r = value metadata 1 - R
value = +Rq
if value relativeto Y
q = value - Y
if q >= 0 & q <= 63
dw q and 111b + 1 shl 3 + r shl 4 + 1 shl 9 + ((q shr 3) and 11b) shl 10 + (q shr 5) shl 13 + 10b shl 14
else
err 'value out of range'
end if
else if value relativeto Z
q = value - Z
if q >= 0 & q <= 63
dw q and 111b + r shl 4 + 1 shl 9 + ((q shr 3) and 11b) shl 10 + (q shr 5) shl 13 + 10b shl 14
else
err 'value out of range'
end if
else
err 'invalid operand'
end if
else
err 'invalid operand'
end if
end macro
macro STS? k,Rr
local value,r
value = +Rr
if value metadata 1 relativeto R & value eq value element 1
r = value metadata 1 - R
value = +k
if value >= 0 & value <= 65535
dw r shl 4 + 1001001b shl 9
dw value
else
err 'address out of range'
end if
else
err 'invalid operand'
end if
end macro
macro TST? Rd
AND Rd,Rd
end macro
macro WDR?
dw 1001'0101'1010'1000b
end macro
macro BREAK? %
if defined %
break ; loop control directive
else
dw 1001'0101'1001'1000b
end if
end macro
define __EVAL_BREAK eval 'break %'
calminstruction BREAK?
assemble __EVAL_BREAK
end calminstruction
PC? equ ($ shr 1)
calminstruction (label) ? definition&
local command
match : command?, definition
jno other
match :: command?, definition
jyes other
arrange definition, =LABEL label =AT =$ =shr 1
assemble definition
assemble command
exit
other:
arrange definition, label definition
assemble definition
end calminstruction
if defined SRAM_START
DSEG?.$ = SRAM_START
else
DSEG?.$ = 60h
end if
DSEG? = 0
define DIRECTIVE DIRECTIVE
macro __ORG? addr*
if ~ DSEG?
org (addr) shl 1
else
org addr
end if
end macro
DIRECTIVE.ORG? equ __ORG
macro __EQU? definition&
match name == value, definition
name? = value
else
err 'invalid definition'
end match
end macro
DIRECTIVE.EQU? equ __EQU
macro __DSEG?
if ~ DSEG?
virtual at DSEG?.$
DSEG? = 1
end if
end macro
DIRECTIVE.DSEG? equ __DSEG
macro __CSEG?
if DSEG?
DSEG?.$ = $
end virtual
DSEG? = 0
end if
end macro
DIRECTIVE.CSEG? equ __CSEG
calminstruction ? line&
local command
match .command, line
jno pass
transform command, DIRECTIVE
jno pass
assemble command
exit
pass:
assemble line
end calminstruction

View File

@ -0,0 +1,54 @@
; This example upon each reset increases the 8-bit counter stored in EEPROM
; and then presents the bits of this value on the pins of port A.
include "avr.inc"
include "..\8051\hex.inc"
include "m16def.inc"
.org 0
rjmp start
start:
ldi r16,RAMEND and $ff
out spl,r16
ldi r16,RAMEND shr 8
out sph,r16
ldi r16,$37
call eeprom_read_byte
mov r17,r16
inc r17
ldi r16,$37
call eeprom_write_byte
ldi r18,11111111b
out DDRA,r18
out PORTA,r17
hang: jmp hang
eeprom_read_byte:
; r16 = EEPROM address
; returns: r16 = byte data
sbic EECR,EEWE
jmp eeprom_read_byte
out EEARL,r16
sbi EECR,EERE
in r16,EEDR
ret
eeprom_write_byte:
; r16 = EEPROM address
; r17 = byte data
cli
while_eeprom_busy:
sbic EECR,EEWE
jmp while_eeprom_busy
out EEARL,r16
out EEDR,r17
sbi EECR,EEMWE
sbi EECR,EEWE
sei
ret

View File

@ -0,0 +1,738 @@
; Register/Bit Definitions for the ATmega16
; I/O Registers
.equ SREG = 0x3f
.equ SPH = 0x3e
.equ SPL = 0x3d
.equ OCR0 = 0x3c
.equ GICR = 0x3b
.equ GIFR = 0x3a
.equ TIMSK = 0x39
.equ TIFR = 0x38
.equ SPMCSR = 0x37
.equ TWCR = 0x36
.equ MCUCR = 0x35
.equ MCUCSR = 0x34
.equ TCCR0 = 0x33
.equ TCNT0 = 0x32
.equ OSCCAL = 0x31
.equ OCDR = 0x31
.equ SFIOR = 0x30
.equ TCCR1A = 0x2f
.equ TCCR1B = 0x2e
.equ TCNT1H = 0x2d
.equ TCNT1L = 0x2c
.equ OCR1AH = 0x2b
.equ OCR1AL = 0x2a
.equ OCR1BH = 0x29
.equ OCR1BL = 0x28
.equ ICR1H = 0x27
.equ ICR1L = 0x26
.equ TCCR2 = 0x25
.equ TCNT2 = 0x24
.equ OCR2 = 0x23
.equ ASSR = 0x22
.equ WDTCR = 0x21
.equ UBRRH = 0x20
.equ UCSRC = 0x20
.equ EEARH = 0x1f
.equ EEARL = 0x1e
.equ EEDR = 0x1d
.equ EECR = 0x1c
.equ PORTA = 0x1b
.equ DDRA = 0x1a
.equ PINA = 0x19
.equ PORTB = 0x18
.equ DDRB = 0x17
.equ PINB = 0x16
.equ PORTC = 0x15
.equ DDRC = 0x14
.equ PINC = 0x13
.equ PORTD = 0x12
.equ DDRD = 0x11
.equ PIND = 0x10
.equ SPDR = 0x0f
.equ SPSR = 0x0e
.equ SPCR = 0x0d
.equ UDR = 0x0c
.equ UCSRA = 0x0b
.equ UCSRB = 0x0a
.equ UBRRL = 0x09
.equ ACSR = 0x08
.equ ADMUX = 0x07
.equ ADCSRA = 0x06
.equ ADCH = 0x05
.equ ADCL = 0x04
.equ TWDR = 0x03
.equ TWAR = 0x02
.equ TWSR = 0x01
.equ TWBR = 0x00
; TCCR0 - Timer/Counter Control Register
.equ CS00 = 0 ; Clock Select 1
.equ CS01 = 1 ; Clock Select 1
.equ CS02 = 2 ; Clock Select 2
.equ WGM01 = 3 ; Waveform Generation Mode 1
.equ CTC0 = WGM01 ; For compatibility
.equ COM00 = 4 ; Compare match Output Mode 0
.equ COM01 = 5 ; Compare Match Output Mode 1
.equ WGM00 = 6 ; Waveform Generation Mode 0
.equ PWM0 = WGM00 ; For compatibility
.equ FOC0 = 7 ; Force Output Compare
; TCNT0 - Timer/Counter Register
.equ TCNT0_0 = 0
.equ TCNT0_1 = 1
.equ TCNT0_2 = 2
.equ TCNT0_3 = 3
.equ TCNT0_4 = 4
.equ TCNT0_5 = 5
.equ TCNT0_6 = 6
.equ TCNT0_7 = 7
; OCR0 - Output Compare Register
.equ OCR0_0 = 0
.equ OCR0_1 = 1
.equ OCR0_2 = 2
.equ OCR0_3 = 3
.equ OCR0_4 = 4
.equ OCR0_5 = 5
.equ OCR0_6 = 6
.equ OCR0_7 = 7
; TIMSK - Timer/Counter Interrupt Mask Register
.equ TOIE0 = 0 ; Timer/Counter0 Overflow Interrupt Enable
.equ OCIE0 = 1 ; Timer/Counter0 Output Compare Match Interrupt register
.equ TOIE1 = 2 ; Timer/Counter1 Overflow Interrupt Enable
.equ OCIE1B = 3 ; Timer/Counter1 Output CompareB Match Interrupt Enable
.equ OCIE1A = 4 ; Timer/Counter1 Output CompareA Match Interrupt Enable
.equ TICIE1 = 5 ; Timer/Counter1 Input Capture Interrupt Enable
.equ TOIE2 = 6 ; Timer/Counter2 Overflow Interrupt Enable
.equ OCIE2 = 7 ; Timer/Counter2 Output Compare Match Interrupt Enable
; TIFR - Timer/Counter Interrupt Flag register
.equ TOV0 = 0 ; Timer/Counter0 Overflow Flag
.equ OCF0 = 1 ; Output Compare Flag 0
.equ TOV2 = 6 ; Timer/Counter2 Overflow Flag
.equ OCF2 = 7 ; Output Compare Flag 2
; SFIOR - Special Function IO Register
.equ PSR10 = 0 ; Prescaler Reset Timer/Counter1 and Timer/Counter0
; TIFR - Timer/Counter Interrupt Flag register
.equ TOV1 = 2 ; Timer/Counter1 Overflow Flag
.equ OCF1B = 3 ; Output Compare Flag 1B
.equ OCF1A = 4 ; Output Compare Flag 1A
.equ ICF1 = 5 ; Input Capture Flag 1
; TCCR1A - Timer/Counter1 Control Register A
.equ WGM10 = 0 ; Waveform Generation Mode
.equ PWM10 = WGM10 ; For compatibility
.equ WGM11 = 1 ; Waveform Generation Mode
.equ PWM11 = WGM11 ; For compatibility
.equ FOC1B = 2 ; Force Output Compare 1B
.equ FOC1A = 3 ; Force Output Compare 1A
.equ COM1B0 = 4 ; Compare Output Mode 1B, bit 0
.equ COM1B1 = 5 ; Compare Output Mode 1B, bit 1
.equ COM1A0 = 6 ; Comparet Ouput Mode 1A, bit 0
.equ COM1A1 = 7 ; Compare Output Mode 1A, bit 1
; TCCR1B - Timer/Counter1 Control Register B
.equ CS10 = 0 ; Prescaler source of Timer/Counter 1
.equ CS11 = 1 ; Prescaler source of Timer/Counter 1
.equ CS12 = 2 ; Prescaler source of Timer/Counter 1
.equ WGM12 = 3 ; Waveform Generation Mode
.equ CTC10 = WGM12 ; For compatibility
.equ CTC1 = WGM12 ; For compatibility
.equ WGM13 = 4 ; Waveform Generation Mode
.equ CTC11 = WGM13 ; For compatibility
.equ ICES1 = 6 ; Input Capture 1 Edge Select
.equ ICNC1 = 7 ; Input Capture 1 Noise Canceler
; GICR - General Interrupt Control Register
.equ GIMSK = GICR ; For compatibility
.equ IVCE = 0 ; Interrupt Vector Change Enable
.equ IVSEL = 1 ; Interrupt Vector Select
.equ INT2 = 5 ; External Interrupt Request 2 Enable
.equ INT0 = 6 ; External Interrupt Request 0 Enable
.equ INT1 = 7 ; External Interrupt Request 1 Enable
; GIFR - General Interrupt Flag Register
.equ INTF2 = 5 ; External Interrupt Flag 2
.equ INTF0 = 6 ; External Interrupt Flag 0
.equ INTF1 = 7 ; External Interrupt Flag 1
; MCUCR - General Interrupt Control Register
.equ ISC00 = 0 ; Interrupt Sense Control 0 Bit 0
.equ ISC01 = 1 ; Interrupt Sense Control 0 Bit 1
.equ ISC10 = 2 ; Interrupt Sense Control 1 Bit 0
.equ ISC11 = 3 ; Interrupt Sense Control 1 Bit 1
; MCUCSR - MCU Control And Status Register
.equ ISC2 = 6 ; Interrupt Sense Control 2
; EEDR - EEPROM Data Register
.equ EEDR0 = 0 ; EEPROM Data Register bit 0
.equ EEDR1 = 1 ; EEPROM Data Register bit 1
.equ EEDR2 = 2 ; EEPROM Data Register bit 2
.equ EEDR3 = 3 ; EEPROM Data Register bit 3
.equ EEDR4 = 4 ; EEPROM Data Register bit 4
.equ EEDR5 = 5 ; EEPROM Data Register bit 5
.equ EEDR6 = 6 ; EEPROM Data Register bit 6
.equ EEDR7 = 7 ; EEPROM Data Register bit 7
; EECR - EEPROM Control Register
.equ EERE = 0 ; EEPROM Read Enable
.equ EEWE = 1 ; EEPROM Write Enable
.equ EEMWE = 2 ; EEPROM Master Write Enable
.equ EEWEE = EEMWE ; For compatibility
.equ EERIE = 3 ; EEPROM Ready Interrupt Enable
; SREG - Status Register
.equ SREG_C = 0 ; Carry Flag
.equ SREG_Z = 1 ; Zero Flag
.equ SREG_N = 2 ; Negative Flag
.equ SREG_V = 3 ; Two's Complement Overflow Flag
.equ SREG_S = 4 ; Sign Bit
.equ SREG_H = 5 ; Half Carry Flag
.equ SREG_T = 6 ; Bit Copy Storage
.equ SREG_I = 7 ; Global Interrupt Enable
; MCUCR - MCU Control Register
;.equ ISC00 = 0 ; Interrupt Sense Control 0 Bit 0
;.equ ISC01 = 1 ; Interrupt Sense Control 0 Bit 1
;.equ ISC10 = 2 ; Interrupt Sense Control 1 Bit 0
;.equ ISC11 = 3 ; Interrupt Sense Control 1 Bit 1
.equ SM0 = 4 ; Sleep Mode Select
.equ SM1 = 5 ; Sleep Mode Select
.equ SE = 6 ; Sleep Enable
.equ SM2 = 7 ; Sleep Mode Select
; MCUCSR - MCU Control And Status Register
.equ MCUSR = MCUCSR; For compatibility
.equ PORF = 0 ; Power-on reset flag
.equ EXTRF = 1 ; External Reset Flag
.equ EXTREF = EXTRF ; For compatibility
.equ BORF = 2 ; Brown-out Reset Flag
.equ WDRF = 3 ; Watchdog Reset Flag
.equ JTRF = 4 ; JTAG Reset Flag
.equ JTD = 7 ; JTAG Interface Disable
; OSCCAL - Oscillator Calibration Value
.equ CAL0 = 0 ; Oscillator Calibration Value Bit0
.equ CAL1 = 1 ; Oscillator Calibration Value Bit1
.equ CAL2 = 2 ; Oscillator Calibration Value Bit2
.equ CAL3 = 3 ; Oscillator Calibration Value Bit3
.equ CAL4 = 4 ; Oscillator Calibration Value Bit4
.equ CAL5 = 5 ; Oscillator Calibration Value Bit5
.equ CAL6 = 6 ; Oscillator Calibration Value Bit6
.equ CAL7 = 7 ; Oscillator Calibration Value Bit7
; SFIOR - Special function I/O register
;.equ PSR10 = 0 ; Prescaler reset
.equ PSR2 = 1 ; Prescaler reset
.equ PUD = 2 ; Pull-up Disable
.equ ADHSM = 3 ; ADC High Speed Mode
.equ ADTS0 = 5 ; ADC High Speed Mode
.equ ADTS1 = 6 ; ADC Auto Trigger Source
.equ ADTS2 = 7 ; ADC Auto Trigger Source
; TCCR2 - Timer/Counter2 Control Register
.equ CS20 = 0 ; Clock Select bit 0
.equ CS21 = 1 ; Clock Select bit 1
.equ CS22 = 2 ; Clock Select bit 2
.equ WGM21 = 3 ; Waveform Generation Mode
.equ CTC2 = WGM21 ; For compatibility
.equ COM20 = 4 ; Compare Output Mode bit 0
.equ COM21 = 5 ; Compare Output Mode bit 1
.equ WGM20 = 6 ; Waveform Genration Mode
.equ PWM2 = WGM20 ; For compatibility
.equ FOC2 = 7 ; Force Output Compare
; TCNT2 - Timer/Counter2
.equ TCNT2_0 = 0 ; Timer/Counter 2 bit 0
.equ TCNT2_1 = 1 ; Timer/Counter 2 bit 1
.equ TCNT2_2 = 2 ; Timer/Counter 2 bit 2
.equ TCNT2_3 = 3 ; Timer/Counter 2 bit 3
.equ TCNT2_4 = 4 ; Timer/Counter 2 bit 4
.equ TCNT2_5 = 5 ; Timer/Counter 2 bit 5
.equ TCNT2_6 = 6 ; Timer/Counter 2 bit 6
.equ TCNT2_7 = 7 ; Timer/Counter 2 bit 7
; OCR2 - Timer/Counter2 Output Compare Register
.equ OCR2_0 = 0 ; Timer/Counter2 Output Compare Register Bit 0
.equ OCR2_1 = 1 ; Timer/Counter2 Output Compare Register Bit 1
.equ OCR2_2 = 2 ; Timer/Counter2 Output Compare Register Bit 2
.equ OCR2_3 = 3 ; Timer/Counter2 Output Compare Register Bit 3
.equ OCR2_4 = 4 ; Timer/Counter2 Output Compare Register Bit 4
.equ OCR2_5 = 5 ; Timer/Counter2 Output Compare Register Bit 5
.equ OCR2_6 = 6 ; Timer/Counter2 Output Compare Register Bit 6
.equ OCR2_7 = 7 ; Timer/Counter2 Output Compare Register Bit 7
; ASSR - Asynchronous Status Register
.equ TCR2UB = 0 ; Timer/counter Control Register2 Update Busy
.equ OCR2UB = 1 ; Output Compare Register2 Update Busy
.equ TCN2UB = 2 ; Timer/Counter2 Update Busy
.equ AS2 = 3 ; Asynchronous Timer/counter2
; SFIOR - Special Function IO Register
;.equ PSR2 = 1 ; Prescaler Reset Timer/Counter2
; SPDR - SPI Data Register
.equ SPDR0 = 0 ; SPI Data Register bit 0
.equ SPDR1 = 1 ; SPI Data Register bit 1
.equ SPDR2 = 2 ; SPI Data Register bit 2
.equ SPDR3 = 3 ; SPI Data Register bit 3
.equ SPDR4 = 4 ; SPI Data Register bit 4
.equ SPDR5 = 5 ; SPI Data Register bit 5
.equ SPDR6 = 6 ; SPI Data Register bit 6
.equ SPDR7 = 7 ; SPI Data Register bit 7
; SPSR - SPI Status Register
.equ SPI2X = 0 ; Double SPI Speed Bit
.equ WCOL = 6 ; Write Collision Flag
.equ SPIF = 7 ; SPI Interrupt Flag
; SPCR - SPI Control Register
.equ SPR0 = 0 ; SPI Clock Rate Select 0
.equ SPR1 = 1 ; SPI Clock Rate Select 1
.equ CPHA = 2 ; Clock Phase
.equ CPOL = 3 ; Clock polarity
.equ MSTR = 4 ; Master/Slave Select
.equ DORD = 5 ; Data Order
.equ SPE = 6 ; SPI Enable
.equ SPIE = 7 ; SPI Interrupt Enable
; UDR - USART I/O Data Register
.equ UDR0 = 0 ; USART I/O Data Register bit 0
.equ UDR1 = 1 ; USART I/O Data Register bit 1
.equ UDR2 = 2 ; USART I/O Data Register bit 2
.equ UDR3 = 3 ; USART I/O Data Register bit 3
.equ UDR4 = 4 ; USART I/O Data Register bit 4
.equ UDR5 = 5 ; USART I/O Data Register bit 5
.equ UDR6 = 6 ; USART I/O Data Register bit 6
.equ UDR7 = 7 ; USART I/O Data Register bit 7
; UCSRA - USART Control and Status Register A
.equ USR = UCSRA ; For compatibility
.equ MPCM = 0 ; Multi-processor Communication Mode
.equ U2X = 1 ; Double the USART transmission speed
.equ UPE = 2 ; Parity Error
.equ PE = UPE ; For compatibility
.equ DOR = 3 ; Data overRun
.equ FE = 4 ; Framing Error
.equ UDRE = 5 ; USART Data Register Empty
.equ TXC = 6 ; USART Transmitt Complete
.equ RXC = 7 ; USART Receive Complete
; UCSRB - USART Control and Status Register B
.equ UCR = UCSRB ; For compatibility
.equ TXB8 = 0 ; Transmit Data Bit 8
.equ RXB8 = 1 ; Receive Data Bit 8
.equ UCSZ2 = 2 ; Character Size
.equ CHR9 = UCSZ2 ; For compatibility
.equ TXEN = 3 ; Transmitter Enable
.equ RXEN = 4 ; Receiver Enable
.equ UDRIE = 5 ; USART Data register Empty Interrupt Enable
.equ TXCIE = 6 ; TX Complete Interrupt Enable
.equ RXCIE = 7 ; RX Complete Interrupt Enable
; UCSRC - USART Control and Status Register C
.equ UCPOL = 0 ; Clock Polarity
.equ UCSZ0 = 1 ; Character Size
.equ UCSZ1 = 2 ; Character Size
.equ USBS = 3 ; Stop Bit Select
.equ UPM0 = 4 ; Parity Mode Bit 0
.equ UPM1 = 5 ; Parity Mode Bit 1
.equ UMSEL = 6 ; USART Mode Select
.equ URSEL = 7 ; Register Select
.equ UBRRHI = UBRRH ; For compatibility
; TWBR - TWI Bit Rate register
.equ I2BR = TWBR ; For compatibility
.equ TWBR0 = 0 ;
.equ TWBR1 = 1 ;
.equ TWBR2 = 2 ;
.equ TWBR3 = 3 ;
.equ TWBR4 = 4 ;
.equ TWBR5 = 5 ;
.equ TWBR6 = 6 ;
.equ TWBR7 = 7 ;
; TWCR - TWI Control Register
.equ I2CR = TWCR ; For compatibility
.equ TWIE = 0 ; TWI Interrupt Enable
.equ I2IE = TWIE ; For compatibility
.equ TWEN = 2 ; TWI Enable Bit
.equ I2EN = TWEN ; For compatibility
.equ ENI2C = TWEN ; For compatibility
.equ TWWC = 3 ; TWI Write Collition Flag
.equ I2WC = TWWC ; For compatibility
.equ TWSTO = 4 ; TWI Stop Condition Bit
.equ I2STO = TWSTO ; For compatibility
.equ TWSTA = 5 ; TWI Start Condition Bit
.equ I2STA = TWSTA ; For compatibility
.equ TWEA = 6 ; TWI Enable Acknowledge Bit
.equ I2EA = TWEA ; For compatibility
.equ TWINT = 7 ; TWI Interrupt Flag
.equ I2INT = TWINT ; For compatibility
; TWSR - TWI Status Register
.equ I2SR = TWSR ; For compatibility
.equ TWPS0 = 0 ; TWI Prescaler
.equ TWS0 = TWPS0 ; For compatibility
.equ I2GCE = TWPS0 ; For compatibility
.equ TWPS1 = 1 ; TWI Prescaler
.equ TWS1 = TWPS1 ; For compatibility
.equ TWS3 = 3 ; TWI Status
.equ I2S3 = TWS3 ; For compatibility
.equ TWS4 = 4 ; TWI Status
.equ I2S4 = TWS4 ; For compatibility
.equ TWS5 = 5 ; TWI Status
.equ I2S5 = TWS5 ; For compatibility
.equ TWS6 = 6 ; TWI Status
.equ I2S6 = TWS6 ; For compatibility
.equ TWS7 = 7 ; TWI Status
.equ I2S7 = TWS7 ; For compatibility
; TWDR - TWI Data register
.equ I2DR = TWDR ; For compatibility
.equ TWD0 = 0 ; TWI Data Register Bit 0
.equ TWD1 = 1 ; TWI Data Register Bit 1
.equ TWD2 = 2 ; TWI Data Register Bit 2
.equ TWD3 = 3 ; TWI Data Register Bit 3
.equ TWD4 = 4 ; TWI Data Register Bit 4
.equ TWD5 = 5 ; TWI Data Register Bit 5
.equ TWD6 = 6 ; TWI Data Register Bit 6
.equ TWD7 = 7 ; TWI Data Register Bit 7
; TWAR - TWI (Slave) Address register
.equ I2AR = TWAR ; For compatibility
.equ TWGCE = 0 ; TWI General Call Recognition Enable Bit
.equ TWA0 = 1 ; TWI (Slave) Address register Bit 0
.equ TWA1 = 2 ; TWI (Slave) Address register Bit 1
.equ TWA2 = 3 ; TWI (Slave) Address register Bit 2
.equ TWA3 = 4 ; TWI (Slave) Address register Bit 3
.equ TWA4 = 5 ; TWI (Slave) Address register Bit 4
.equ TWA5 = 6 ; TWI (Slave) Address register Bit 5
.equ TWA6 = 7 ; TWI (Slave) Address register Bit 6
; SFIOR - Special Function IO Register
.equ ACME = 3 ; Analog Comparator Multiplexer Enable
; ACSR - Analog Comparator Control And Status Register
.equ ACIS0 = 0 ; Analog Comparator Interrupt Mode Select bit 0
.equ ACIS1 = 1 ; Analog Comparator Interrupt Mode Select bit 1
.equ ACIC = 2 ; Analog Comparator Input Capture Enable
.equ ACIE = 3 ; Analog Comparator Interrupt Enable
.equ ACI = 4 ; Analog Comparator Interrupt Flag
.equ ACO = 5 ; Analog Compare Output
.equ ACBG = 6 ; Analog Comparator Bandgap Select
.equ ACD = 7 ; Analog Comparator Disable
; ADMUX - The ADC multiplexer Selection Register
.equ MUX0 = 0 ; Analog Channel and Gain Selection Bits
.equ MUX1 = 1 ; Analog Channel and Gain Selection Bits
.equ MUX2 = 2 ; Analog Channel and Gain Selection Bits
.equ MUX3 = 3 ; Analog Channel and Gain Selection Bits
.equ MUX4 = 4 ; Analog Channel and Gain Selection Bits
.equ ADLAR = 5 ; Left Adjust Result
.equ REFS0 = 6 ; Reference Selection Bit 0
.equ REFS1 = 7 ; Reference Selection Bit 1
; ADCSRA - The ADC Control and Status register
.equ ADPS0 = 0 ; ADC Prescaler Select Bits
.equ ADPS1 = 1 ; ADC Prescaler Select Bits
.equ ADPS2 = 2 ; ADC Prescaler Select Bits
.equ ADIE = 3 ; ADC Interrupt Enable
.equ ADIF = 4 ; ADC Interrupt Flag
.equ ADATE = 5 ; When this bit is written to one,the Timer/Counter2 prescaler will be reset.The bit will be cleared by hardware after the operation is performed.Writing a zero to this bit will have no effect.This bit will always be read as zero if Timer/Counter2 is clocked by the internal CPU clock.If this bit is written when Timer/Counter2 is operating in asynchronous mode,the bit will remain one until the prescaler has been reset.
.equ ADFR = ADATE ; For compatibility
.equ ADSC = 6 ; ADC Start Conversion
.equ ADEN = 7 ; ADC Enable
; ADCH - ADC Data Register High Byte
.equ ADCH0 = 0 ; ADC Data Register High Byte Bit 0
.equ ADCH1 = 1 ; ADC Data Register High Byte Bit 1
.equ ADCH2 = 2 ; ADC Data Register High Byte Bit 2
.equ ADCH3 = 3 ; ADC Data Register High Byte Bit 3
.equ ADCH4 = 4 ; ADC Data Register High Byte Bit 4
.equ ADCH5 = 5 ; ADC Data Register High Byte Bit 5
.equ ADCH6 = 6 ; ADC Data Register High Byte Bit 6
.equ ADCH7 = 7 ; ADC Data Register High Byte Bit 7
; ADCL - ADC Data Register Low Byte
.equ ADCL0 = 0 ; ADC Data Register Low Byte Bit 0
.equ ADCL1 = 1 ; ADC Data Register Low Byte Bit 1
.equ ADCL2 = 2 ; ADC Data Register Low Byte Bit 2
.equ ADCL3 = 3 ; ADC Data Register Low Byte Bit 3
.equ ADCL4 = 4 ; ADC Data Register Low Byte Bit 4
.equ ADCL5 = 5 ; ADC Data Register Low Byte Bit 5
.equ ADCL6 = 6 ; ADC Data Register Low Byte Bit 6
.equ ADCL7 = 7 ; ADC Data Register Low Byte Bit 7
; OCDR - On-Chip Debug Related Register in I/O Memory
.equ OCDR0 = 0 ; On-Chip Debug Register Bit 0
.equ OCDR1 = 1 ; On-Chip Debug Register Bit 1
.equ OCDR2 = 2 ; On-Chip Debug Register Bit 2
.equ OCDR3 = 3 ; On-Chip Debug Register Bit 3
.equ OCDR4 = 4 ; On-Chip Debug Register Bit 4
.equ OCDR5 = 5 ; On-Chip Debug Register Bit 5
.equ OCDR6 = 6 ; On-Chip Debug Register Bit 6
.equ OCDR7 = 7 ; On-Chip Debug Register Bit 7
.equ IDRD = OCDR7 ; For compatibility
; MCUCSR - MCU Control And Status Register
;.equ JTRF = 4 ; JTAG Reset Flag
;.equ JTD = 7 ; JTAG Interface Disable
; SPMCSR - Store Program Memory Control Register
.equ SPMCR = SPMCSR ; For compatibility
.equ SPMEN = 0 ; Store Program Memory Enable
.equ PGERS = 1 ; Page Erase
.equ PGWRT = 2 ; Page Write
.equ BLBSET = 3 ; Boot Lock Bit Set
.equ RWWSRE = 4 ; Read While Write section read enable
.equ ASRE = RWWSRE ; For compatibility
.equ RWWSB = 6 ; Read While Write Section Busy
.equ ASB = RWWSB ; For compatibility
.equ SPMIE = 7 ; SPM Interrupt Enable
; PORTA - Port A Data Register
.equ PORTA0 = 0 ; Port A Data Register bit 0
.equ PA0 = 0 ; For compatibility
.equ PORTA1 = 1 ; Port A Data Register bit 1
.equ PA1 = 1 ; For compatibility
.equ PORTA2 = 2 ; Port A Data Register bit 2
.equ PA2 = 2 ; For compatibility
.equ PORTA3 = 3 ; Port A Data Register bit 3
.equ PA3 = 3 ; For compatibility
.equ PORTA4 = 4 ; Port A Data Register bit 4
.equ PA4 = 4 ; For compatibility
.equ PORTA5 = 5 ; Port A Data Register bit 5
.equ PA5 = 5 ; For compatibility
.equ PORTA6 = 6 ; Port A Data Register bit 6
.equ PA6 = 6 ; For compatibility
.equ PORTA7 = 7 ; Port A Data Register bit 7
.equ PA7 = 7 ; For compatibility
; DDRA - Port A Data Direction Register
.equ DDA0 = 0 ; Data Direction Register, Port A, bit 0
.equ DDA1 = 1 ; Data Direction Register, Port A, bit 1
.equ DDA2 = 2 ; Data Direction Register, Port A, bit 2
.equ DDA3 = 3 ; Data Direction Register, Port A, bit 3
.equ DDA4 = 4 ; Data Direction Register, Port A, bit 4
.equ DDA5 = 5 ; Data Direction Register, Port A, bit 5
.equ DDA6 = 6 ; Data Direction Register, Port A, bit 6
.equ DDA7 = 7 ; Data Direction Register, Port A, bit 7
; PINA - Port A Input Pins
.equ PINA0 = 0 ; Input Pins, Port A bit 0
.equ PINA1 = 1 ; Input Pins, Port A bit 1
.equ PINA2 = 2 ; Input Pins, Port A bit 2
.equ PINA3 = 3 ; Input Pins, Port A bit 3
.equ PINA4 = 4 ; Input Pins, Port A bit 4
.equ PINA5 = 5 ; Input Pins, Port A bit 5
.equ PINA6 = 6 ; Input Pins, Port A bit 6
.equ PINA7 = 7 ; Input Pins, Port A bit 7
; PORTB - Port B Data Register
.equ PORTB0 = 0 ; Port B Data Register bit 0
.equ PB0 = 0 ; For compatibility
.equ PORTB1 = 1 ; Port B Data Register bit 1
.equ PB1 = 1 ; For compatibility
.equ PORTB2 = 2 ; Port B Data Register bit 2
.equ PB2 = 2 ; For compatibility
.equ PORTB3 = 3 ; Port B Data Register bit 3
.equ PB3 = 3 ; For compatibility
.equ PORTB4 = 4 ; Port B Data Register bit 4
.equ PB4 = 4 ; For compatibility
.equ PORTB5 = 5 ; Port B Data Register bit 5
.equ PB5 = 5 ; For compatibility
.equ PORTB6 = 6 ; Port B Data Register bit 6
.equ PB6 = 6 ; For compatibility
.equ PORTB7 = 7 ; Port B Data Register bit 7
.equ PB7 = 7 ; For compatibility
; DDRB - Port B Data Direction Register
.equ DDB0 = 0 ; Port B Data Direction Register bit 0
.equ DDB1 = 1 ; Port B Data Direction Register bit 1
.equ DDB2 = 2 ; Port B Data Direction Register bit 2
.equ DDB3 = 3 ; Port B Data Direction Register bit 3
.equ DDB4 = 4 ; Port B Data Direction Register bit 4
.equ DDB5 = 5 ; Port B Data Direction Register bit 5
.equ DDB6 = 6 ; Port B Data Direction Register bit 6
.equ DDB7 = 7 ; Port B Data Direction Register bit 7
; PINB - Port B Input Pins
.equ PINB0 = 0 ; Port B Input Pins bit 0
.equ PINB1 = 1 ; Port B Input Pins bit 1
.equ PINB2 = 2 ; Port B Input Pins bit 2
.equ PINB3 = 3 ; Port B Input Pins bit 3
.equ PINB4 = 4 ; Port B Input Pins bit 4
.equ PINB5 = 5 ; Port B Input Pins bit 5
.equ PINB6 = 6 ; Port B Input Pins bit 6
.equ PINB7 = 7 ; Port B Input Pins bit 7
; PORTC - Port C Data Register
.equ PORTC0 = 0 ; Port C Data Register bit 0
.equ PC0 = 0 ; For compatibility
.equ PORTC1 = 1 ; Port C Data Register bit 1
.equ PC1 = 1 ; For compatibility
.equ PORTC2 = 2 ; Port C Data Register bit 2
.equ PC2 = 2 ; For compatibility
.equ PORTC3 = 3 ; Port C Data Register bit 3
.equ PC3 = 3 ; For compatibility
.equ PORTC4 = 4 ; Port C Data Register bit 4
.equ PC4 = 4 ; For compatibility
.equ PORTC5 = 5 ; Port C Data Register bit 5
.equ PC5 = 5 ; For compatibility
.equ PORTC6 = 6 ; Port C Data Register bit 6
.equ PC6 = 6 ; For compatibility
.equ PORTC7 = 7 ; Port C Data Register bit 7
.equ PC7 = 7 ; For compatibility
; DDRC - Port C Data Direction Register
.equ DDC0 = 0 ; Port C Data Direction Register bit 0
.equ DDC1 = 1 ; Port C Data Direction Register bit 1
.equ DDC2 = 2 ; Port C Data Direction Register bit 2
.equ DDC3 = 3 ; Port C Data Direction Register bit 3
.equ DDC4 = 4 ; Port C Data Direction Register bit 4
.equ DDC5 = 5 ; Port C Data Direction Register bit 5
.equ DDC6 = 6 ; Port C Data Direction Register bit 6
.equ DDC7 = 7 ; Port C Data Direction Register bit 7
; PINC - Port C Input Pins
.equ PINC0 = 0 ; Port C Input Pins bit 0
.equ PINC1 = 1 ; Port C Input Pins bit 1
.equ PINC2 = 2 ; Port C Input Pins bit 2
.equ PINC3 = 3 ; Port C Input Pins bit 3
.equ PINC4 = 4 ; Port C Input Pins bit 4
.equ PINC5 = 5 ; Port C Input Pins bit 5
.equ PINC6 = 6 ; Port C Input Pins bit 6
.equ PINC7 = 7 ; Port C Input Pins bit 7
; PORTD - Port D Data Register
.equ PORTD0 = 0 ; Port D Data Register bit 0
.equ PD0 = 0 ; For compatibility
.equ PORTD1 = 1 ; Port D Data Register bit 1
.equ PD1 = 1 ; For compatibility
.equ PORTD2 = 2 ; Port D Data Register bit 2
.equ PD2 = 2 ; For compatibility
.equ PORTD3 = 3 ; Port D Data Register bit 3
.equ PD3 = 3 ; For compatibility
.equ PORTD4 = 4 ; Port D Data Register bit 4
.equ PD4 = 4 ; For compatibility
.equ PORTD5 = 5 ; Port D Data Register bit 5
.equ PD5 = 5 ; For compatibility
.equ PORTD6 = 6 ; Port D Data Register bit 6
.equ PD6 = 6 ; For compatibility
.equ PORTD7 = 7 ; Port D Data Register bit 7
.equ PD7 = 7 ; For compatibility
; DDRD - Port D Data Direction Register
.equ DDD0 = 0 ; Port D Data Direction Register bit 0
.equ DDD1 = 1 ; Port D Data Direction Register bit 1
.equ DDD2 = 2 ; Port D Data Direction Register bit 2
.equ DDD3 = 3 ; Port D Data Direction Register bit 3
.equ DDD4 = 4 ; Port D Data Direction Register bit 4
.equ DDD5 = 5 ; Port D Data Direction Register bit 5
.equ DDD6 = 6 ; Port D Data Direction Register bit 6
.equ DDD7 = 7 ; Port D Data Direction Register bit 7
; PIND - Port D Input Pins
.equ PIND0 = 0 ; Port D Input Pins bit 0
.equ PIND1 = 1 ; Port D Input Pins bit 1
.equ PIND2 = 2 ; Port D Input Pins bit 2
.equ PIND3 = 3 ; Port D Input Pins bit 3
.equ PIND4 = 4 ; Port D Input Pins bit 4
.equ PIND5 = 5 ; Port D Input Pins bit 5
.equ PIND6 = 6 ; Port D Input Pins bit 6
.equ PIND7 = 7 ; Port D Input Pins bit 7
; WDTCR - Watchdog Timer Control Register
.equ WDP0 = 0 ; Watch Dog Timer Prescaler bit 0
.equ WDP1 = 1 ; Watch Dog Timer Prescaler bit 1
.equ WDP2 = 2 ; Watch Dog Timer Prescaler bit 2
.equ WDE = 3 ; Watch Dog Enable
.equ WDTOE = 4 ; RW
.equ WDDE = WDTOE ; For compatibility
; Locks Bits
.equ LB1 = 0 ; Lock bit
.equ LB2 = 1 ; Lock bit
.equ BLB01 = 2 ; Boot Lock bit
.equ BLB02 = 3 ; Boot Lock bit
.equ BLB11 = 4 ; Boot lock bit
.equ BLB12 = 5 ; Boot lock bit
; Low Fuse Bits
.equ CKSEL0 = 0 ; Select Clock Source
.equ CKSEL1 = 1 ; Select Clock Source
.equ CKSEL2 = 2 ; Select Clock Source
.equ CKSEL3 = 3 ; Select Clock Source
.equ SUT0 = 4 ; Select start-up time
.equ SUT1 = 5 ; Select start-up time
.equ BODEN = 6 ; Brown out detector enable
.equ BODLEVEL= 7 ; Brown out detector trigger level
; High Fuse Bits
.equ BOOTRST = 0 ; Select Reset Vector
.equ BOOTSZ0 = 1 ; Select Boot Size
.equ BOOTSZ1 = 2 ; Select Boot Size
.equ EESAVE = 3 ; EEPROM memory is preserved through chip erase
.equ CKOPT = 4 ; Oscillator Options
.equ SPIEN = 5 ; Enable Serial programming and Data Downloading
.equ JTAGEN = 6 ; Enable JTAG
.equ OCDEN = 7 ; Enable OCD
; Data Memory
.equ FLASHEND = 0x1fff ; Note: Word address
.equ IOEND = 0x003f
.equ SRAM_START = 0x0060
.equ SRAM_SIZE = 1024
.equ RAMEND = 0x045f
.equ XRAMEND = 0x0000
.equ E2END = 0x01ff
.equ EEPROMEND = 0x01ff
.equ EEADRBITS = 9
; Bootloader
.equ NRWW_START_ADDR = 0x1c00
.equ NRWW_STOP_ADDR = 0x1fff
.equ RWW_START_ADDR = 0x0
.equ RWW_STOP_ADDR = 0x1bff
.equ PAGESIZE = 64
.equ FIRSTBOOTSTART = 0x1f80
.equ SECONDBOOTSTART = 0x1f00
.equ THIRDBOOTSTART = 0x1e00
.equ FOURTHBOOTSTART = 0x1c00
.equ SMALLBOOTSTART = FIRSTBOOTSTART
.equ LARGEBOOTSTART = FOURTHBOOTSTART
; Interrupt Vectors
.equ INT0addr = 0x0002 ; External Interrupt Request 0
.equ INT1addr = 0x0004 ; External Interrupt Request 1
.equ OC2addr = 0x0006 ; Timer/Counter2 Compare Match
.equ OVF2addr = 0x0008 ; Timer/Counter2 Overflow
.equ ICP1addr = 0x000a ; Timer/Counter1 Capture Event
.equ OC1Aaddr = 0x000c ; Timer/Counter1 Compare Match A
.equ OC1Baddr = 0x000e ; Timer/Counter1 Compare Match B
.equ OVF1addr = 0x0010 ; Timer/Counter1 Overflow
.equ OVF0addr = 0x0012 ; Timer/Counter0 Overflow
.equ SPIaddr = 0x0014 ; Serial Transfer Complete
.equ URXCaddr = 0x0016 ; USART, Rx Complete
.equ UDREaddr = 0x0018 ; USART Data Register Empty
.equ UTXCaddr = 0x001a ; USART, Tx Complete
.equ ADCCaddr = 0x001c ; ADC Conversion Complete
.equ ERDYaddr = 0x001e ; EEPROM Ready
.equ ACIaddr = 0x0020 ; Analog Comparator
.equ TWIaddr = 0x0022 ; 2-wire Serial Interface
.equ INT2addr = 0x0024 ; External Interrupt Request 2
.equ OC0addr = 0x0026 ; Timer/Counter0 Compare Match
.equ SPMRaddr = 0x0028 ; Store Program Memory Ready
.equ INT_VECTORS_SIZE = 42 ; size in words

View File

@ -0,0 +1 @@
fasmg counter.asm counter.hex

View File

@ -0,0 +1,134 @@
; This example uses a very simple set of macroinstructions to generate
; the basic structures of JVM class file.
; Please refer to "The Java Virtual Machine Specification" for the detailed
; information on this file format.
include 'jclass.inc'
format binary as 'class'
u4 0xcafebabe ; magic
u2 0,49 ; minor and major version
constant_pool
_Code constant_utf8 'Code'
_init constant_utf8 '<init>'
_main constant_utf8 'main'
_void_arrstr constant_utf8 '([Ljava/lang/String;)V'
Test_class constant_class _Test
_Test constant_utf8 'Test'
Object_init constant_methodref Object_class,init_method
Object_class constant_class _Object
_Object constant_utf8 'java/lang/Object'
init_method constant_nameandtype _init,_void
_void constant_utf8 '()V'
System.out constant_fieldref System_class,out_field
System_class constant_class _System
_System constant_utf8 'java/lang/System'
out_field constant_nameandtype _out,PrintStream_type
_out constant_utf8 'out'
PrintStream_type constant_utf8 'Ljava/io/PrintStream;'
PrintStream_println constant_methodref PrintStream_class,println_method
PrintStream_class constant_class _PrintStream
_PrintStream constant_utf8 'java/io/PrintStream'
println_method constant_nameandtype _println,_void_str
_println constant_utf8 'println'
_void_str constant_utf8 '(Ljava/lang/String;)V'
Integer_toString constant_methodref Integer_class,toString_method
Integer_class constant_class _Integer
_Integer constant_utf8 'java/lang/Integer'
toString_method constant_nameandtype _toString,_str_int
_toString constant_utf8 'toString'
_str_int constant_utf8 '(I)Ljava/lang/String;'
number constant_integer 17
end constant_pool
u2 ACC_PUBLIC+ACC_SUPER ; access flags
u2 Test_class ; this class
u2 Object_class ; super class
interfaces
end interfaces
fields
end fields
methods
method_info ACC_PUBLIC, _init, _void ; public void Test()
attribute _Code
u2 1 ; max_stack
u2 1 ; max_locals
bytecode
aload 0
invokespecial Object_init
return
end bytecode
exceptions
end exceptions
attributes
end attributes
end attribute
end method_info
method_info ACC_PUBLIC+ACC_STATIC, _main, _void_arrstr ; public static void main(String[] args)
attribute _Code
u2 3 ; max_stack
u2 2 ; max_locals
bytecode
ldc number
istore 1
example_loop:
iload 1
dup
imul
invokestatic Integer_toString
getstatic System.out
swap
invokevirtual PrintStream_println
iinc 1,-1
iload 1
ifne example_loop
return
end bytecode
exceptions
end exceptions
attributes
end attributes
end attribute
end method_info
end methods
attributes
end attributes

View File

@ -0,0 +1,797 @@
T_BOOLEAN = 4
T_CHAR = 5
T_FLOAT = 6
T_DOUBLE = 7
T_BYTE = 8
T_SHORT = 9
T_INT = 10
T_LONG = 11
macro aaload
db 0x32
end macro
macro aastore
db 0x53
end macro
macro aconst_null
db 0x01
end macro
macro aload index
if index<0
err "invalid index"
else if index<=3
db 0x2a+index
else if index<100h
db 0x19,index
else
db 0xc4,0x19,(index) shr 8,(index) and 0FFh
end if
end macro
macro anewarray class
db 0xbd,(class) shr 8,(class) and 0FFh
end macro
macro areturn
db 0xb0
end macro
macro arraylength
db 0xbe
end macro
macro astore index
if index<0
err "invalid index"
else if index<=3
db 0x4b+index
else if index<100h
db 0x3a,index
else
db 0xc4,0x3a,(index) shr 8,(index) and 0FFh
end if
end macro
macro athrow
db 0xbf
end macro
macro baload
db 0x33
end macro
macro bastore
db 0x54
end macro
macro bipush byte
if byte>-1 & byte<=5
db 0x03+byte
else
db 0x10,byte
end if
end macro
macro caload
db 0x34
end macro
macro castore
db 0x55
end macro
macro checkcast class
db 0xc0,(class) shr 8,(class) and 0FFh
end macro
macro d2f
db 0x90
end macro
macro d2i
db 0x8e
end macro
macro d2l
db 0x8f
end macro
macro dadd
db 0x63
end macro
macro daload
db 0x31
end macro
macro dastore
db 0x52
end macro
macro dcmpg
db 0x98
end macro
macro dcmpl
db 0x97
end macro
macro dconst_0
db 0x0e
end macro
macro dconst_1
db 0x0f
end macro
macro ddiv
db 0x6f
end macro
macro dload index
if index<0
err "invalid index"
else if index<=3
db 0x26+index
else if index<100h
db 0x18,index
else
db 0xc4,0x18,(index) shr 8,(index) and 0FFh
end if
end macro
macro dmul
db 0x6b
end macro
macro dneg
db 0x77
end macro
macro drem
db 0x73
end macro
macro dreturn
db 0xaf
end macro
macro dstore index
if index<0
err "invalid index"
else if index<=3
db 0x47+index
else if index<100h
db 0x39,index
else
db 0xc4,0x39,(index) shr 8,(index) and 0FFh
end if
end macro
macro dsub
db 0x67
end macro
macro dup
db 0x59
end macro
macro dup_x1
db 0x5a
end macro
macro dup_x2
db 0x5b
end macro
macro dup2
db 0x5c
end macro
macro dup2_x1
db 0x5d
end macro
macro dup2_x2
db 0x5e
end macro
macro f2d
db 0x8d
end macro
macro f2i
db 0x8b
end macro
macro f2l
db 0x8c
end macro
macro fadd
db 0x62
end macro
macro faload
db 0x30
end macro
macro fastore
db 0x51
end macro
macro fcmpg
db 0x96
end macro
macro fcmpl
db 0x95
end macro
macro fconst_0
db 0x0b
end macro
macro fconst_1
db 0x0c
end macro
macro fconst_2
db 0x0d
end macro
macro fdiv
db 0x6e
end macro
macro fload index
if index<0
err "invalid index"
else if index<=3
db 0x22+index
else if index<100h
db 0x17,index
else
db 0xc4,0x17,(index) shr 8,(index) and 0FFh
end if
end macro
macro fmul
db 0x6a
end macro
macro fneg
db 0x76
end macro
macro frem
db 0x72
end macro
macro freturn
db 0xae
end macro
macro fstore index
if index<0
err "invalid index"
else if index<=3
db 0x43+index
else if index<100h
db 0x38,index
else
db 0xc4,0x38,(index) shr 8,(index) and 0FFh
end if
end macro
macro fsub
db 0x66
end macro
macro getfield index
db 0xb4,(index) shr 8,(index) and 0FFh
end macro
macro getstatic index
db 0xb2,(index) shr 8,(index) and 0FFh
end macro
macro goto branch
offset = branch-$
if offset>=-8000h & offset<8000h
db 0xa7,offset shr 8,offset and 0FFh
else
db 0xc8,offset shr 24,(offset shr 16) and 0FFh,(offset shr 8) and 0FFh,offset and 0FFh
end if
end macro
macro goto_w branch
offset = branch-$
db 0xc8,offset shr 24,(offset shr 16) and 0FFh,(offset shr 8) and 0FFh,offset and 0FFh
end macro
macro i2b
db 0x91
end macro
macro i2c
db 0x92
end macro
macro i2d
db 0x87
end macro
macro i2f
db 0x86
end macro
macro i2l
db 0x85
end macro
macro i2s
db 0x93
end macro
macro iadd
db 0x60
end macro
macro iaload
db 0x2e
end macro
macro iand
db 0x7e
end macro
macro iastore
db 0x4f
end macro
macro iconst_m1
db 0x02
end macro
macro iconst_0
db 0x03
end macro
macro iconst_1
db 0x04
end macro
macro iconst_2
db 0x05
end macro
macro iconst_3
db 0x06
end macro
macro iconst_4
db 0x07
end macro
macro iconst_5
db 0x08
end macro
macro idiv
db 0x6c
end macro
macro if_acmpeq branch
offset = branch-$
db 0xa5,offset shr 8,offset and 0FFh
end macro
macro if_acmpne branch
offset = branch-$
db 0xa6,offset shr 8,offset and 0FFh
end macro
macro if_icmpeq branch
offset = branch-$
db 0x9f,offset shr 8,offset and 0FFh
end macro
macro if_icmpne branch
offset = branch-$
db 0xa0,offset shr 8,offset and 0FFh
end macro
macro if_icmplt branch
offset = branch-$
db 0xa1,offset shr 8,offset and 0FFh
end macro
macro if_icmpge branch
offset = branch-$
db 0xa2,offset shr 8,offset and 0FFh
end macro
macro if_icmpgt branch
offset = branch-$
db 0xa3,offset shr 8,offset and 0FFh
end macro
macro if_icmple branch
offset = branch-$
db 0xa4,offset shr 8,offset and 0FFh
end macro
macro ifeq branch
offset = branch-$
db 0x99,offset shr 8,offset and 0FFh
end macro
macro ifne branch
offset = branch-$
db 0x9a,offset shr 8,offset and 0FFh
end macro
macro iflt branch
offset = branch-$
db 0x9b,offset shr 8,offset and 0FFh
end macro
macro ifge branch
offset = branch-$
db 0x9c,offset shr 8,offset and 0FFh
end macro
macro ifgt branch
offset = branch-$
db 0x9d,offset shr 8,offset and 0FFh
end macro
macro ifle branch
offset = branch-$
db 0x9e,offset shr 8,offset and 0FFh
end macro
macro ifnonnull branch
offset = branch-$
db 0xc7,offset shr 8,offset and 0FFh
end macro
macro ifnull branch
offset = branch-$
db 0xc6,offset shr 8,offset and 0FFh
end macro
macro iinc index,const
if index<0
err "invalid index"
else if index<100h & const<80h & const>=-80h
db 0x84,index,const
else
db 0xc4,0x84,(index) shr 8,(index) and 0FFh,(const) shr 8,(const) and 0FFh
end if
end macro
macro iload index
if index<0
err "invalid index"
else if index<=3
db 0x1a+index
else if index<100h
db 0x15,index
else
db 0xc4,0x15,(index) shr 8,(index) and 0FFh
end if
end macro
macro imul
db 0x68
end macro
macro ineg
db 0x74
end macro
macro instanceof index
db 0xc1,(index) shr 8,(index) and 0FFh
end macro
macro invokedynamic index
db 0xba,(index) shr 8,(index) and 0FFh,0,0
end macro
macro invokeinterface index,count
db 0xb9,(index) shr 8,(index) and 0FFh,count
end macro
macro invokespecial index
db 0xb7,(index) shr 8,(index) and 0FFh
end macro
macro invokestatic index
db 0xb8,(index) shr 8,(index) and 0FFh
end macro
macro invokevirtual index
db 0xb6,(index) shr 8,(index) and 0FFh
end macro
macro ior
db 0x80
end macro
macro irem
db 0x70
end macro
macro ireturn
db 0xac
end macro
macro ishl
db 0x78
end macro
macro ishr
db 0x7a
end macro
macro istore index
if index<0
err "invalid index"
else if index<=3
db 0x3b+index
else if index<100h
db 0x36,index
else
db 0xc4,0x36,(index) shr 8,(index) and 0FFh
end if
end macro
macro isub
db 0x64
end macro
macro iushr
db 0x7c
end macro
macro ixor
db 0x82
end macro
macro jsr branch
offset = branch-$
if offset>=-8000h & offset<8000h
db 0xa8,offset shr 8,offset and 0FFh
else
db 0xc9,offset shr 24,(offset shr 16) and 0FFh,(offset shr 8) and 0FFh,offset and 0FFh
end if
end macro
macro jsr_w branch
offset = branch-$
db 0xc9,offset shr 24,(offset shr 16) and 0FFh,(offset shr 8) and 0FFh,offset and 0FFh
end macro
macro l2d
db 0x8a
end macro
macro l2f
db 0x89
end macro
macro l2i
db 0x88
end macro
macro ladd
db 0x61
end macro
macro laload
db 0x2f
end macro
macro land
db 0x7f
end macro
macro lastore
db 0x50
end macro
macro lcmp
db 0x94
end macro
macro lconst_0
db 0x09
end macro
macro lconst_1
db 0x0a
end macro
macro ldc index
if index<0
err "invalid index"
else if index<100h
db 0x12,index
else
db 0x13,(index) shr 8,(index) and 0FFh
end if
end macro
macro ldc_w index
db 0x13,(index) shr 8,(index) and 0FFh
end macro
macro ldc2_w index
db 0x14,(index) shr 8,(index) and 0FFh
end macro
macro ldiv
db 0x6d
end macro
macro lload index
if index<0
err "invalid index"
else if index<=3
db 0x1e+index
else if index<100h
db 0x16,index
else
db 0xc4,0x16,(index) shr 8,(index) and 0FFh
end if
end macro
macro lmul
db 0x69
end macro
macro lneg
db 0x75
end macro
macro lookupswitch
; db 0xab,...
err "not implemented yet"
end macro
macro lor
db 0x81
end macro
macro lrem
db 0x71
end macro
macro lreturn
db 0xad
end macro
macro lshl
db 0x79
end macro
macro lshr
db 0x7b
end macro
macro lstore index
if index<0
err "invalid index"
else if index<=3
db 0x3f+index
else if index<100h
db 0x37,index
else
db 0xc4,0x37,(index) shr 8,(index) and 0FFh
end if
end macro
macro lsub
db 0x65
end macro
macro lushr
db 0x7d
end macro
macro lxor
db 0x83
end macro
macro monitorenter
db 0xc2
end macro
macro monitorexit
db 0xc3
end macro
macro multianewarray index,dimensions
db 0xc5,(index) shr 8,(index) and 0FFh,dimensions
end macro
macro new index
db 0xbb,(index) shr 8,(index) and 0FFh
end macro
macro newarray atype
db 0xbc,atype
end macro
macro nop
db 0x00
end macro
macro pop
db 0x57
end macro
macro pop2
db 0x58
end macro
macro putfield index
db 0xb5,(index) shr 8,(index) and 0FFh
end macro
macro putstatic index
db 0xb3,(index) shr 8,(index) and 0FFh
end macro
macro ret index
if index<0
err "invalid index"
else if index<100h
db 0xa9,index
else
db 0xc4,0xa9,(index) shr 8,(index) and 0FFh
end if
end macro
macro return
db 0xb1
end macro
macro saload
db 0x35
end macro
macro sastore
db 0x56
end macro
macro sipush short
db 0x11,(short) shr 8,(short) and 0FFh
end macro
macro swap
db 0x5f
end macro
macro tableswitch
; db 0xaa,...
err "not implemented yet"
end macro
macro breakpoint
db 0xca
end macro
macro impdep1
db 0xfe
end macro
macro impdep2
db 0xff
end macro

View File

@ -0,0 +1,254 @@
ACC_PUBLIC = 0x0001
ACC_PRIVATE = 0x0002
ACC_PROTECTED = 0x0004
ACC_STATIC = 0x0008
ACC_FINAL = 0x0010
ACC_SUPER = 0x0020
ACC_SYNCHRONIZED = 0x0020
ACC_NATIVE = 0x0200
ACC_INTERFACE = 0x0200
ACC_ABSTRACT = 0x0400
ACC_STRICT = 0x0800
macro u1 values&
irp v,values
db v
end irp
end macro
macro u2 values&
irp v,values
db (v) bswap 2
end irp
end macro
macro u4 values&
irp v,values
db (v) bswap 4
end irp
end macro
macro constant_pool
u2 constant_pool_count
constant_pool_counter = 1
struc constant_utf8 string&
. = constant_pool_counter
constant_pool_counter = constant_pool_counter + 1
local data,length
u1 1
u2 length
data: db string
length = $ - data
end struc
struc constant_integer value
. = constant_pool_counter
constant_pool_counter = constant_pool_counter + 1
u1 3
u4 value
end struc
struc constant_float value
. = constant_pool_counter
constant_pool_counter = constant_pool_counter + 1
u1 4
u4 value
end struc
struc constant_long value
. = constant_pool_counter
constant_pool_counter = constant_pool_counter + 1
u1 5
u4 value shr 32,value and 0FFFFFFFFh
end struc
struc constant_double value
. = constant_pool_counter
constant_pool_counter = constant_pool_counter + 1
u1 6
u4 value shr 32,value and 0FFFFFFFFh
end struc
struc constant_class name_index
. = constant_pool_counter
constant_pool_counter = constant_pool_counter + 1
u1 7
u2 name_index
end struc
struc constant_string string_index
. = constant_pool_counter
constant_pool_counter = constant_pool_counter + 1
u1 8
u2 string_index
end struc
struc constant_fieldref class_index,name_and_type_index
. = constant_pool_counter
constant_pool_counter = constant_pool_counter + 1
u1 9
u2 class_index
u2 name_and_type_index
end struc
struc constant_methodref class_index,name_and_type_index
. = constant_pool_counter
constant_pool_counter = constant_pool_counter + 1
u1 10
u2 class_index
u2 name_and_type_index
end struc
struc constant_interfacemethodref class_index,name_and_type_index
. = constant_pool_counter
constant_pool_counter = constant_pool_counter + 1
u1 11
u2 class_index
u2 name_and_type_index
end struc
struc constant_nameandtype name_index,descriptor_index
. = constant_pool_counter
constant_pool_counter = constant_pool_counter + 1
u1 12
u2 name_index
u2 descriptor_index
end struc
end macro
macro end?.constant_pool
constant_pool_count = constant_pool_counter
restruc constant_utf8,constant_integer,constant_float,constant_long,constant_double
restruc constant_class,constant_string
restruc constant_fieldref,constant_methodref,constant_interfacemethodref,constant_nameandtype
end macro
macro interfaces
u2 interfaces_count
interfaces_counter = 0
macro interface interface
interfaces_counter = interfaces_counter + 1
u2 interface
end macro
end macro
macro end?.interfaces
interfaces_count = interfaces_counter
purge interface
end macro
macro attributes
local count,counter
u2 count
counter = 0
attributes_count equ count
attributes_counter equ counter
macro attribute attribute_name_index
match sym,attributes_counter
sym = sym + 1
end match
u2 attribute_name_index
local start,length
u4 length
start = $
attribute_start equ start
attribute_length equ length
end macro
macro end?.attribute
match sym,attribute_length
sym = $ - attribute_start
end match
restore atribute_start,attribute_length
end macro
end macro
macro end?.attributes
match sym,attributes_count
sym = attributes_counter
end match
restore attributes_count,attributes_counter
purge attribute
end macro
macro fields
u2 fields_count
fields_counter = 0
macro field_info access_flags,name_index,descriptor_index
fields_counter = fields_counter + 1
u2 access_flags
u2 name_index
u2 descriptor_index
attributes
end macro
macro end?.field_info
end?.attributes
end macro
end macro
macro end?.fields
fields_count = fields_counter
purge field_info,end?.field_info
end macro
macro methods
u2 methods_count
methods_counter = 0
macro method_info access_flags,name_index,descriptor_index
methods_counter = methods_counter + 1
u2 access_flags
u2 name_index
u2 descriptor_index
attributes
end macro
macro end?.method_info
end?.attributes
end macro
end macro
macro end?.methods
methods_count = methods_counter
purge method_info,end?.method_info
end macro
macro bytecode
local length
bytecode_length equ length
u4 length
bytecode_offset = $
org 0
end macro
macro end?.bytecode
match sym,bytecode_length
sym = $
end match
org bytecode_offset+bytecode_length
restore bytecode_length
end macro
macro exceptions
local length
exception_table_length equ length
u2 length
exception_counter = 0
macro exception start_pc,end_pc,handler_pc,catch_type
exception_counter = exception_counter + 1
u2 start_pc
u2 end_pc
u2 handler_pc
u2 catch_type
end macro
end macro
macro end?.exceptions
match sym,exception_table_length
sym = exception_counter
end match
restore exception_table_length
end macro
include 'bytecode.inc'

View File

@ -0,0 +1 @@
fasmg Test.asm Test.class

View File

@ -0,0 +1,14 @@
include '8086.inc'
org 100h
display_text = 9
mov ah,display_text
mov dx,hello
int 21h
int 20h
hello db 'Hello world!',24h

View File

@ -0,0 +1,383 @@
include '8086.inc'
define @aux @aux
calminstruction push? src*
call x86.parse_operand@src, src
check @src.size and not 2
jno main
err 'invalid operand size'
main:
check @src.type = 'mem'
jyes push_mem
check @src.type = 'reg'
jyes push_reg
check @src.type = 'sreg'
jyes push_sreg
check @src.type = 'imm'
jyes push_imm
err 'invalid operand'
exit
push_mem:
xcall x86.store_instruction@src, (0FFh),(110b)
exit
push_reg:
emit 1, 50h + @src.rm
exit
push_sreg:
emit 1, 6 + @src.rm shl 3
exit
push_imm:
check @src.imm relativeto 0 & @src.imm < 80h & @src.imm >= -80h
jyes push_simm
check @src.imm relativeto 0 & @src.imm - 10000h >= -80h & @src.imm < 10000h
jyes push_simm_wrap
emit 1, 68h
asm dw @src.imm
exit
push_simm_wrap:
compute @src.imm, @src.imm - 10000h
push_simm:
emit 1, 6Ah
emit 1, @src.imm
exit
end calminstruction
calminstruction x86.pop_instruction size:0,dest*
call x86.parse_operand@dest, dest
check @dest.size and not 2
jno main
err 'invalid operand size'
main:
check @dest.type = 'mem'
jyes pop_mem
check @dest.type = 'reg'
jyes pop_reg
check @dest.type = 'sreg'
jyes pop_sreg
invalid_operand:
err 'invalid operand'
exit
pop_mem:
xcall x86.store_instruction@dest, (8Fh),(0)
exit
pop_reg:
emit 1, 58h + @dest.rm
exit
pop_sreg:
check @dest.rm = 1
jyes invalid_operand
emit 1, 7 + @dest.rm shl 3
exit
end calminstruction
iterate <instr>, push,pop
calminstruction instr? operand
local head, tail
match head tail, operand
jno plain
transform head, x86.compact
jno plain
match {head}, head
jno plain
loop:
arrange operand, =instr head
assemble operand
match head tail, tail
jno final
transform head, x86.compact
jno error
match {head}, head
jyes loop
error:
err 'only register operands allowed in compact syntax'
exit
final:
transform tail, x86.compact
jno error
match {operand}, tail
jno error
plain:
arrange operand, =instr operand
assemble operand
end calminstruction
end iterate
iterate <instr,opcode>, pusha,60h, popa,61h, insb,6Ch, outsb,6Eh, insw,6Dh, outsw,6Fh, leave,0C9h
calminstruction instr?
emit 1, opcode
end calminstruction
end iterate
calminstruction imul? dest*,src&
local size
call x86.parse_operand@dest, dest
match , src
jyes imul_rm
local src1, src2
match src1 =, src2, src
jyes imul_second_source
call x86.parse_operand@src, src
check @dest.size = 0 & @src.size = 0
jyes operand_size_not_specified
check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size
jyes operand_sizes_do_not_match
compute size, @dest.size or @src.size
check @src.type = 'imm' & @dest.type = 'reg'
jno invalid_combination_of_operands
compute @aux.type, @src.type
compute @aux.imm, @src.imm
compute @src.type, @dest.type
compute @src.mod, @dest.mod
compute @src.rm, @dest.rm
jump main
imul_second_source:
call x86.parse_operand@src, src1
call x86.parse_operand@aux, src2
check @dest.size = 0 & @src.size = 0 & @aux.size = 0
jyes operand_size_not_specified
compute size, @dest.size or @src.size or @aux.size
check (@dest.size & @dest.size <> size) | (@src.size & @src.size <> size) | (@aux.size & @aux.size <> size)
jyes operand_sizes_do_not_match
jump main
operand_size_not_specified:
err 'operand size not specified'
compute size, 0
jump main
operand_sizes_do_not_match:
err 'operand sizes do not match'
compute size, 0
jump main
main:
check @aux.type = 'imm' & ( @src.type = 'mem' | @src.type = 'reg' ) & @dest.type = 'reg' & size = 2
jyes imul_reg_rm_imm
invalid_combination_of_operands:
err 'invalid combination of operands'
exit
imul_rm:
check @dest.size
jyes imul_rm_size_ok
err 'operand size not specified'
imul_rm_size_ok:
check @dest.type = 'mem' | @dest.type = 'reg'
jno invalid_combination_of_operands
check @dest.size < 2
jyes imul_rm_8bit
xcall x86.store_instruction@dest, (0F7h),(5)
exit
imul_rm_8bit:
xcall x86.store_instruction@dest, (0F6h),(5)
exit
imul_reg_rm_imm:
check @aux.imm relativeto 0 & @aux.imm < 80h & @aux.imm >= -80h
jyes imul_reg_rm_simm
check @aux.imm relativeto 0 & @aux.imm - 10000h >= -80h & @aux.imm < 10000h
jyes imul_reg_rm_simm_wrap
xcall x86.store_instruction@src, (69h),@dest.rm,size,@aux.imm
exit
imul_reg_rm_simm_wrap:
compute @aux.imm, @aux.imm - 1 shl (size shl 3)
imul_reg_rm_simm:
xcall x86.store_instruction@src, (6Bh),@dest.rm,byte,@aux.imm
exit
end calminstruction
iterate <instr,postbyte>, rol,0, ror,1, rcl,2, rcr,3, shl,4, sal, 4, shr,5, sar,7
calminstruction instr? dest*,cnt*
call x86.parse_operand@dest, dest
call x86.parse_operand@src, cnt
check @dest.size = 0
jyes operand_size_not_specified
check @src.size and not 1
jyes invalid_operand_size
main:
check @src.type = 'reg' & @src.size = 1 & @src.rm = 1 & ( @dest.type = 'reg' | @dest.type = 'mem' )
jyes shift_rm_cl
check @src.type = 'imm' & ( @dest.type = 'reg' | @dest.type = 'mem' )
jyes shift_rm_imm
err 'invalid combination of operands'
exit
shift_rm_cl:
check @dest.size < 2
jyes shift_r8_cl
xcall x86.store_instruction@dest, (0D3h),(postbyte)
exit
shift_r8_cl:
xcall x86.store_instruction@dest, (0D2h),(postbyte)
exit
shift_rm_imm:
check @dest.size < 2
jyes shift_rm8_imm
check @src.imm = 1
jyes shift_rm_1
xcall x86.store_instruction@dest, (0C1h),(postbyte),byte,@src.imm
exit
shift_rm_1:
xcall x86.store_instruction@dest, (0D1h),(postbyte)
exit
shift_rm8_imm:
check @src.imm = 1
jyes shift_rm8_1
xcall x86.store_instruction@dest, (0C0h),(postbyte),byte,@src.imm
exit
shift_rm8_1:
xcall x86.store_instruction@dest, (0D0h),(postbyte)
exit
operand_size_not_specified:
err 'operand size not specified'
jump main
invalid_operand_size:
err 'invalid operand size'
jump main
end calminstruction
end iterate
calminstruction ins? dest*,src*
call x86.parse_operand@dest, dest
call x86.parse_operand@src, src
check @dest.size
jyes size_ok
err 'operand size not specified'
compute size, 0
size_ok:
check @src.type = 'reg' & @src.size = 2 & @src.rm = 2 & @dest.type = 'mem' & @dest.mod = 0 & @dest.rm = 5 & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h )
jno invalid_combination_of_operands
check @dest.size = 2
jyes ins_word
assemble x86.insb
exit
ins_word:
assemble x86.insw
exit
invalid_combination_of_operands:
err 'invalid combination of operands'
exit
end calminstruction
calminstruction outs? dest*,src*
call x86.parse_operand@dest, dest
call x86.parse_operand@src, src
check @src.size
jyes size_ok
err 'operand size not specified'
size_ok:
check @dest.type = 'reg' & @dest.size = 2 & @dest.rm = 2 & @src.type = 'mem' & @src.mod = 0 & @src.rm = 4
jno invalid_combination_of_operands
check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh
jyes segment_prefix_ok
emit 1, @src.segment_prefix
segment_prefix_ok:
check @src.size = 2
jyes outs_word
assemble x86.outsb
exit
outs_word:
assemble x86.outsw
exit
operand_size_not_specified:
err 'operand size not specified'
compute size, 0
jump size_ok
operand_sizes_do_not_match:
err 'operand sizes do not match'
compute size, 0
jump size_ok
invalid_combination_of_operands:
err 'invalid combination of operands'
exit
end calminstruction
calminstruction enter? alloc*,nesting*
call x86.parse_operand@src, alloc
call x86.parse_operand@aux, nesting
check (@src.size and not 2) | (@aux.size and not 1)
jno size_ok
err 'invalid operand size'
size_ok:
check @src.type = 'imm' & @aux.type = 'imm'
jno operand_ok
err 'invalid operand'
exit
operand_ok:
emit 1, 0C8h
asm dw @src.imm
emit 1, @aux.imm
end calminstruction
calminstruction bound? dest*,src*
call x86.parse_operand@dest, dest
call x86.parse_operand@src, src
check @src.type = 'mem' & @dest.type = 'reg'
jno invalid_combination_of_operands
check @dest.size = 2
jno invalid_operand_size
check @src.size and not @dest.size
jno size_ok
err 'operand sizes do not match'
size_ok:
xcall x86.store_instruction@src, (62h),@dest.rm
exit
invalid_operand_size:
err 'invalid operand size'
invalid_combination_of_operands:
err 'invalid combination of operands'
end calminstruction

View File

@ -0,0 +1,86 @@
include '80186.inc'
iterate <instr,opcode>, loadall,<0Fh,05h>, clts,<0Fh,06h>
calminstruction instr?
asm db opcode
end calminstruction
end iterate
calminstruction arpl? dest*,src*
call x86.parse_operand@dest, dest
call x86.parse_operand@src, src
check @src.type = 'reg' & (@dest.type = 'mem' | @dest.type = 'reg')
jno invalid_combination_of_operands
check @src.size = 2
jno invalid_operand_size
check @dest.size and not @src.size
jno size_ok
err 'operand sizes do not match'
jump size_ok
invalid_operand_size:
err 'invalid operand size'
size_ok:
xcall x86.store_instruction@dest, (63h),@src.rm
exit
invalid_combination_of_operands:
err 'invalid combination of operands'
end calminstruction
iterate <instr,ext,postbyte>, sldt,0,0, str,0,1, lldt,0,2, ltr,0,3, verr,0,4, verw,0,5, smsw,1,4, lmsw,1,6
calminstruction instr? dest*
call x86.parse_operand@dest, dest
check @dest.size and not 2
jno size_ok
err 'invalid operand size'
size_ok:
check @dest.type = 'reg' | @dest.type = 'mem'
jyes operand_ok
err 'invalid operand'
exit
operand_ok:
xcall x86.store_instruction@dest, <0Fh,ext>,(postbyte)
end calminstruction
end iterate
iterate <instr,postbyte>, lgdt,2, lidt,3, sgdt,0, sidt,1
calminstruction instr? dest*
call x86.parse_operand@dest, dest
check @dest.type = 'mem'
jyes operand_ok
err 'invalid operand'
exit
operand_ok:
check @dest.size and not 5
jno store_instruction
err 'invalid operand size'
store_instruction:
xcall x86.store_instruction@dest, <0Fh,1>,(postbyte)
exit
end calminstruction
end iterate
iterate <instr,ext>, lar,2, lsl,3
calminstruction instr? dest*,src*
call x86.parse_operand@dest, dest
call x86.parse_operand@src, src
check @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg')
jno invalid_combination_of_operands
check @src.size and not 2
jno size_ok
err 'invalid operand size'
size_ok:
xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm
exit
invalid_combination_of_operands:
err 'invalid combination of operands'
end calminstruction
end iterate

View File

@ -0,0 +1,16 @@
if ~ defined i80287
restore i80287 ; this ensures that symbol cannot be forward-referenced
i80287 = 1
include '8087.inc'
purge feni?,fneni?,fdisi?,fndisi?
calminstruction fsetpm?
emit 1, 0DBh
emit 1, 0E4h
end calminstruction
end if

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
if ~ defined i80387
restore i80387 ; this ensures that symbol cannot be forward-referenced
i80387 = 1
include '80287.inc'
purge fsetpm?
iterate <instr,opcode>, fprem1,<0D9h,0F5h>, fsincos,<0D9h,0FBh>, fsin,<0D9h,0FEh>, fcos,<0D9h,0FFh>, fucompp,<0DAh,0E9h>
calminstruction instr?
asm db opcode
end calminstruction
end iterate
iterate <instr,postbyte>, fucom,4, fucomp,5
calminstruction instr? src:st1
call x87.parse_operand@src, src
check @src.type = 'streg'
jno invalid_operand
xcall x86.store_instruction@src, (0DDh),(postbyte)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, fldenv,4, fnstenv,6
calminstruction instr? dest*
call x86.parse_operand@dest, dest
check @dest.size & ( ( x86.mode = 16 & @dest.size <> 14 ) | ( x86.mode = 32 & @dest.size <> 28 ) )
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_instruction@dest, (0D9h),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, fldenvw,4, fnstenvw,6
calminstruction instr? dest*
call x86.parse_operand@dest, dest
check @dest.size and not 14
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_operand_prefix, (2)
xcall x86.store_instruction@dest, (0D9h),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, fldenvd,4, fnstenvd,6
calminstruction instr? dest*
call x86.parse_operand@dest, dest
check @dest.size and not 28
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_operand_prefix, (4)
xcall x86.store_instruction@dest, (0D9h),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, frstor,4, fnsave,6
calminstruction instr? dest*
call x86.parse_operand@dest, dest
check @dest.size & ( ( x86.mode = 16 & @dest.size <> 94 ) | ( x86.mode = 32 & @dest.size <> 108 ) )
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_instruction@dest, (0DDh),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, frstorw,4, fnsavew,6
calminstruction instr? dest*
call x86.parse_operand@dest, dest
check @dest.size and not 94
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_operand_prefix, (2)
xcall x86.store_instruction@dest, (0DDh),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, frstord,4, fnsaved,6
calminstruction instr? dest*
call x86.parse_operand@dest, dest
check @dest.size and not 108
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_operand_prefix, (4)
xcall x86.store_instruction@dest, (0DDh),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate op, stenvw, stenvd, savew, saved
calminstruction f#op? dest*
asm fwait?
asm fn#op? dest
end calminstruction
end iterate
end if

View File

@ -0,0 +1,62 @@
include '80386.inc'
purge loadall?
purge xbts?,ibts?
iterate <instr,ext>, cmpxchg,0B0h, xadd,0C0h
calminstruction instr? dest*,src*
call x86.parse_operand@dest, dest
call x86.parse_operand@src, src
check @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' )
jyes xadd_rm_reg
err 'invalid combination of operands'
exit
xadd_rm_reg:
check @dest.size and not @src.size
jno size_ok
err 'operand sizes do not match'
size_ok:
check @src.size > 1
jno xadd_rm_reg_8bit
call x86.select_operand_prefix@dest, @src.size
xcall x86.store_instruction@dest, <0Fh,ext+1>,@src.rm
exit
xadd_rm_reg_8bit:
xcall x86.store_instruction@dest, <0Fh,ext>,@src.rm
end calminstruction
end iterate
calminstruction bswap? dest*
call x86.parse_operand@dest, dest
check @dest.type = 'reg' & @dest.size = 4
jyes operand_ok
err 'invalid operand'
exit
operand_ok:
call x86.store_operand_prefix, @dest.size
emit 1, 0Fh
emit 1, 0C8h + @dest.rm and 111b
end calminstruction
calminstruction invlpg? dest*
call x86.parse_operand@dest, dest
check @dest.type = 'mem'
jyes operand_ok
err 'invalid operand'
exit
operand_ok:
xcall x86.store_instruction@dest, <0Fh,1>,(7)
end calminstruction
iterate <instr,opcode>, invd,<0Fh,8>, wbinvd,<0Fh,9>
define x86.instr? db opcode
calminstruction instr?
assemble x86.instr?
end calminstruction
end iterate

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,555 @@
if ~ defined i8087
restore i8087 ; this ensures that symbol cannot be forward-referenced
i8087 = 1
define x87 x87
element st?
repeat 8, i:0
element st#i? : st? + i
end repeat
define x86.qword? :8
define x86.tword? :10
define x86.tbyte? :10
iterate context, @dest,@src,@src2,@aux
namespace context
calminstruction x87.parse_operand#context operand
local i
match =st?(i), operand
jyes indexed_streg_operand
call x86.parse_operand#context, operand
check type = 'imm' & size = 0
jno done
check imm eq 1 elementof imm & 1 metadataof imm relativeto st?
jyes streg_operand
check imm relativeto st? & imm = st?
jno done
compute type, 'streg'
compute mod, 11b
compute rm, 0
exit
streg_operand:
compute type, 'streg'
compute mod, 11b
compute rm, 1 metadataof imm - st?
exit
indexed_streg_operand:
compute size, 0
compute type, 'streg'
compute mod, 11b
compute rm, +i
done:
end calminstruction
end namespace
end iterate
iterate <instr,opcode>, fwait,9Bh, wait,9Bh, fnop,<0D9h,0D0h>, \
fchs,<0D9h,0E0h>, fabs,<0D9h,0E1h>, ftst,<0D9h,0E4h>, fxam,<0D9h,0E5h>, fld1,<0D9h,0E8h>, \
fldl2t,<0D9h,0E9h>, fldl2e,<0D9h,0EAh>, fldpi,<0D9h,0EBh>, fldlg2,<0D9h,0ECh>, fldln2,<0D9h,0EDh>, fldz,<0D9h,0EEh>, \
f2xm1,<0D9h,0F0h>, fyl2x,<0D9h,0F1h>, fptan,<0D9h,0F2h>, fpatan,<0D9h,0F3h>, fxtract,<0D9h,0F4h>, fdecstp,<0D9h,0F6h>, fincstp,<0D9h,0F7h>, fprem,<0D9h,0F8h>, \
fyl2xp1,<0D9h,0F9h>, fsqrt,<0D9h,0FAh>, frndint,<0D9h,0FCh>, fscale,<0D9h,0FDh>, \
fneni,<0DBh,0E0h>, fndisi,<0DBh,0E1h>, fnclex,<0DBh,0E2h>, fninit,<0DBh,0E3h>, \
fcompp,<0DEh,0D9h>
calminstruction instr?
asm db opcode
end calminstruction
end iterate
iterate op, eni, disi, clex, init
calminstruction f#op?
asm fwait?
asm fn#op?
end calminstruction
end iterate
iterate <instr,postbyte>, fadd,0, fmul,1, fsub,4, fsubr,5, fdiv,6, fdivr,7
calminstruction instr? operand&
local dest, src
match dest=,src, operand
jyes st
call x87.parse_operand@dest, operand
check @dest.type = 'mem'
jno invalid_combination_of_operands
check @dest.size = 4
jyes mem_dword
check @dest.size = 8
jyes mem_qword
check @dest.size
jno unknown_size
err 'invalid operand size'
jump mem_dword
unknown_size:
err 'operand size not specified'
mem_dword:
xcall x86.store_instruction@dest, (0D8h),(postbyte)
exit
mem_qword:
xcall x86.store_instruction@dest, (0DCh),(postbyte)
exit
st:
call x87.parse_operand@dest, dest
call x87.parse_operand@src, src
check @dest.type = 'streg' & @src.type = 'streg'
jno invalid_combination_of_operands
check @dest.rm = 0
jyes st0_sti
check @src.rm = 0
jyes sti_st0
jump invalid_combination_of_operands
st0_sti:
emit 1, 0D8h
emit 1, 11b shl 6 + postbyte shl 3 + @src.rm
exit
sti_st0:
check postbyte >= 4
jyes switched
emit 1, 0DCh
emit 1, 11b shl 6 + postbyte shl 3 + @dest.rm
exit
switched:
emit 1, 0DCh
emit 1, 11b shl 6 + (postbyte xor 1) shl 3 + @dest.rm
exit
invalid_combination_of_operands:
err 'invalid combination of operands'
end calminstruction
end iterate
iterate <instr,postbyte>, faddp,0, fmulp,1, fsubrp,4, fsubp,5, fdivrp,6, fdivp,7
calminstruction instr? operand&
local dest, src
match , operand
jyes default
match dest=,src, operand
jno invalid_combination_of_operands
call x87.parse_operand@dest, dest
call x87.parse_operand@src, src
check @dest.type = 'streg' & @src.type = 'streg' & @src.rm = 0
jyes ok
invalid_combination_of_operands:
err 'invalid combination of operands'
exit
default:
compute @dest.rm, 1
ok:
emit 1, 0DEh
emit 1, 11b shl 6 + postbyte shl 3 + @dest.rm
end calminstruction
end iterate
iterate <instr,postbyte>, fcom,2, fcomp,3
calminstruction instr? src:st1
call x87.parse_operand@src, src
check @src.type = 'streg'
jyes st
check @src.type = 'mem'
jno invalid_operand
check @src.size = 4
jyes mem_dword
check @src.size = 8
jyes mem_qword
check @src.size
jno unknown_size
err 'invalid operand size'
jump mem_dword
unknown_size:
err 'operand size not specified'
mem_dword: st:
xcall x86.store_instruction@src, (0D8h),(postbyte)
exit
mem_qword:
xcall x86.store_instruction@src, (0DCh),(postbyte)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, fiadd,0, fimul,1, ficom,2, ficomp,3, fisub,4, fisubr,5, fidiv,6, fidivr,7
calminstruction instr? src*
call x87.parse_operand@src, src
check @src.type = 'mem'
jno invalid_operand
check @src.size = 2
jyes mem_word
check @src.size = 4
jyes mem_dword
check @src.size
jno unknown_size
err 'invalid operand size'
jump mem_word
unknown_size:
err 'operand size not specified'
mem_word:
xcall x86.store_instruction@src, (0DEh),(postbyte)
exit
mem_dword:
xcall x86.store_instruction@src, (0DAh),(postbyte)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
calminstruction fld? src*
call x87.parse_operand@src, src
check @src.type = 'streg'
jyes st
check @src.type = 'mem'
jno invalid_operand
check @src.size = 4
jyes mem_dword
check @src.size = 8
jyes mem_qword
check @src.size = 10
jyes mem_tword
check @src.size
jno unknown_size
err 'invalid operand size'
jump mem_dword
unknown_size:
err 'operand size not specified'
mem_dword: st:
xcall x86.store_instruction@src, (0D9h),(0)
exit
mem_qword:
xcall x86.store_instruction@src, (0DDh),(0)
exit
mem_tword:
xcall x86.store_instruction@src, (0DBh),(5)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
calminstruction fst? dest*
call x87.parse_operand@dest, dest
check @dest.type = 'streg'
jyes st
check @dest.type = 'mem'
jno invalid_operand
check @dest.size = 4
jyes mem_dword
check @dest.size = 8
jyes mem_qword
check @dest.size
jno unknown_size
err 'invalid operand size'
jump mem_dword
unknown_size:
err 'operand size not specified'
mem_dword:
xcall x86.store_instruction@dest, (0D9h),(2)
exit
mem_qword: st:
xcall x86.store_instruction@dest, (0DDh),(2)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
calminstruction fstp? dest*
call x87.parse_operand@dest, dest
check @dest.type = 'streg'
jyes st
check @dest.type = 'mem'
jno invalid_operand
check @dest.size = 4
jyes mem_dword
check @dest.size = 8
jyes mem_qword
check @dest.size = 10
jyes mem_tword
check @dest.size
jno unknown_size
err 'invalid operand size'
jump mem_dword
unknown_size:
err 'operand size not specified'
mem_dword:
xcall x86.store_instruction@dest, (0D9h),(3)
exit
mem_qword: st:
xcall x86.store_instruction@dest, (0DDh),(3)
exit
mem_tword:
xcall x86.store_instruction@dest, (0DBh),(7)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
calminstruction fild? src*
call x87.parse_operand@src, src
check @src.type = 'mem'
jno invalid_operand
check @src.size = 2
jyes mem_word
check @src.size = 4
jyes mem_dword
check @src.size = 8
jyes mem_qword
check @src.size
jno unknown_size
err 'invalid operand size'
jump mem_word
unknown_size:
err 'operand size not specified'
mem_word:
xcall x86.store_instruction@src, (0DFh),(0)
exit
mem_dword:
xcall x86.store_instruction@src, (0DBh),(0)
exit
mem_qword:
xcall x86.store_instruction@src, (0DFh),(5)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
calminstruction fist? dest*
call x87.parse_operand@dest, dest
check @dest.type = 'mem'
jno invalid_operand
check @dest.size = 2
jyes mem_word
check @dest.size = 4
jyes mem_dword
check @dest.size
jno unknown_size
err 'invalid operand size'
jump mem_word
unknown_size:
err 'operand size not specified'
mem_word:
xcall x86.store_instruction@dest, (0DFh),(2)
exit
mem_dword:
xcall x86.store_instruction@dest, (0DBh),(2)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
calminstruction fistp? dest*
call x87.parse_operand@dest, dest
check @dest.type = 'mem'
jno invalid_operand
check @dest.size = 2
jyes mem_word
check @dest.size = 4
jyes mem_dword
check @dest.size = 8
jyes mem_qword
check @dest.size
jno unknown_size
err 'invalid operand size'
jump mem_word
unknown_size:
err 'operand size not specified'
mem_word:
xcall x86.store_instruction@dest, (0DFh),(3)
exit
mem_dword:
xcall x86.store_instruction@dest, (0DBh),(3)
exit
mem_qword:
xcall x86.store_instruction@dest, (0DFh),(7)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
calminstruction fisttp? dest*
call x87.parse_operand@dest, dest
check @dest.type = 'mem'
jno invalid_operand
check @dest.size = 2
jyes mem_word
check @dest.size = 4
jyes mem_dword
check @dest.size = 8
jyes mem_qword
check @dest.size
jno unknown_size
err 'invalid operand size'
jump mem_word
unknown_size:
err 'operand size not specified'
mem_word:
xcall x86.store_instruction@dest, (0DFh),(1)
exit
mem_dword:
xcall x86.store_instruction@dest, (0DBh),(1)
exit
mem_qword:
xcall x86.store_instruction@dest, (0DDh),(1)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
iterate <instr,postbyte>, fbld,4, fbstp,6
calminstruction instr? src*
call x87.parse_operand@src, src
check @src.type = 'mem'
jno invalid_operand
check @src.size and not 10
jyes invalid_operand_size
xcall x86.store_instruction@src, (0DFh),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
calminstruction fxch? src:st1
call x87.parse_operand@src, src
check @src.type = 'streg'
jno invalid_operand
emit 1, 0D9h
emit 1, 11b shl 6 + 1 shl 3 + @src.rm
exit
invalid_operand:
err 'invalid operand'
end calminstruction
iterate <instr,basecode>, ffree,0DDh, ffreep,0DFh
calminstruction instr? src*
call x87.parse_operand@src, src
check @src.type = 'streg'
jno invalid_operand
emit 1, basecode
emit 1, 11b shl 6 + @src.rm
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
calminstruction fnstsw? dest*
call x86.parse_operand@dest, dest
check @dest.size and not 2
jyes invalid_operand_size
check @dest.type = 'mem'
jyes mem
check @dest.type = 'reg' & @dest.rm = 0
jno invalid_operand
emit 1, 0DFh
emit 1, 0E0h
exit
mem:
xcall x86.store_instruction@dest, (0DDh),(7)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
iterate <instr,postbyte>, fldcw,5, fnstcw,7
calminstruction instr? dest*
call x86.parse_operand@dest, dest
check @dest.size and not 2
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_instruction@dest, (0D9h),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, fldenv,4, fnstenv,6
calminstruction instr? dest*
call x86.parse_operand@dest, dest
check @dest.size and not 14
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_instruction@dest, (0D9h),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, frstor,4, fnsave,6
calminstruction instr? dest*
call x86.parse_operand@dest, dest
check @dest.size and not 94
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_instruction@dest, (0DDh),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate op, stsw, stcw, stenv, save
calminstruction f#op? dest*
asm fwait?
asm fn#op? dest
end calminstruction
end iterate
end if

View File

@ -0,0 +1,21 @@
iterate <instr,pfx>, adcx,66h, adox,0F3h
macro instr? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg')
if @src.size <> 0 & @src.size <> @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8 & x86.mode = 64
@src.prefix = 48h
else if @dest.size <> 4
err 'invalid operand size'
end if
@src.opcode_prefix = pfx
x86.store_instruction@src <0Fh,38h,0F6h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate

View File

@ -0,0 +1,43 @@
include 'sse.inc'
iterate <instr,supp>, aesdec,0DEh, aesenc,0DCh, aesimc,0DBh, aesdeclast,0DFh, aesenclast,0DDh
macro instr? dest*,src*
SSE.basic_instruction 66h,<38h,supp>,16,dest,src
end macro
end iterate
iterate <instr,supp>, aeskeygenassist,0DFh
macro instr? dest*,src*,imm*
SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm
end macro
end iterate
if defined AVX
iterate <instr,opcode>, aesenc,0DCh, aesenclast,0DDh, aesdec,0DEh, aesdeclast,0DFh
macro v#instr? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W0,opcode,16,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, aesimc,0DBh
macro v#instr? dest*,src*
AVX.single_source_instruction VEX_66_0F38_W0,opcode,16,dest,src
end macro
end iterate
iterate <instr,opcode>, aeskeygenassist,0DFh
macro v#instr? dest*,src*,imm*
AVX.single_source_instruction_imm8 VEX_66_0F3A_W0,opcode,16,dest,src,imm
end macro
end iterate
end if

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,502 @@
if ~ defined AVX2
restore AVX2 ; this ensures that symbol cannot be forward-referenced
AVX2 = 1
include 'avx.inc'
iterate context, @dest,@src,@src2,@aux
namespace context
define visize
calminstruction AVX.parse_vsib_operand#context operand
local i, pre, suf
compute segment_prefix, 0
compute size, 0
compute displacement_size, 0
transform operand
match pre suf, operand
jno no_size_prefix
transform pre, x86
jno no_size_prefix
match :size, pre
jno no_size_prefix
arrange operand, suf
no_size_prefix:
match [address], operand
jyes memory_operand
match =ptr? address, operand
jyes memory_operand
jump invalid_operand
memory_operand:
compute type, 'mem'
match segment:address, address
jno segment_prefix_ok
check segment eq 1 elementof segment & 1 metadataof segment relativeto x86.sreg
jno invalid_operand
compute segment, 1 metadataof segment - x86.sreg
check segment >= 4
jyes segment_prefix_386
compute segment_prefix, 26h + segment shl 3
jump segment_prefix_ok
segment_prefix_386:
compute segment_prefix, 64h + segment-4
segment_prefix_ok:
match pre suf, address
jno no_address_size_prefix
transform pre, x86
jno no_address_size_prefix
match :pre, pre
jno no_address_size_prefix
arrange address, suf
check pre = 4 | pre = 8
jno invalid_address_size
compute mode, pre shl 3
no_address_size_prefix:
compute mode, 0
compute scale, 0
compute index, 0
compute base, 0
compute auto_relative, 0
check size
jyes size_override
compute size, sizeof address
size_override:
compute address, address
compute base_registers, 0
compute index_registers, 0
compute i, 1
extract_registers:
check i > elementsof address
jyes registers_extracted
check i metadataof address relativeto SSE.reg | i metadataof address relativeto AVX.reg
jyes index_term
check i metadataof address relativeto x86.r32 | i metadataof address relativeto x86.r64
jno next_term
compute base_registers, base_registers + i elementof address * i scaleof address
jump next_term
index_term:
compute index_registers, index_registers + i elementof address * i scaleof address
next_term:
compute i, i+1
jump extract_registers
registers_extracted:
compute displacement, address - base_registers - index_registers
compute auto_relative, 0
check elementsof index_registers = 1
jno invalid_address
compute scale, 1 scaleof index_registers
compute index, 0 scaleof (1 metadataof index_registers)
check scale and (scale-1) | scale > 8
jyes invalid_address
check 1 metadataof index_registers relativeto SSE.reg
jyes xmm_index
compute visize, 32
jump index_ok
xmm_index:
compute visize, 16
index_ok:
compute rm, 4
check elementsof base_registers = 1 & 1 scaleof base_registers = 1
jyes base_and_index
check elementsof base_registers = 0
jno invalid_address
compute base, 5
compute displacement_size, 4
compute mod, 0
compute mode, x86.mode
check mode > 16
jyes ready
compute mode, 32
jump ready
base_and_index:
compute base, 0 scaleof (1 metadataof base_registers)
check mode & mode <> 0 scaleof (1 metadataof (1 metadataof base_registers)) shl 3
jyes invalid_address
compute mode, 0 scaleof (1 metadataof (1 metadataof base_registers)) shl 3
setup_displacement:
check displacement relativeto 0
jno displacement_32bit
check displacement = 0 & rm and 111b <> 5 & (rm <> 4 | base and 111b <> 5)
jyes displacement_empty
check displacement < 80h & displacement >= -80h
jyes displacement_8bit
check displacement - 1 shl mode >= -80h & displacement < 1 shl mode
jyes displacement_8bit_wrap
displacement_32bit:
compute displacement_size, 4
compute mod, 2
jump ready
displacement_8bit_wrap:
compute displacement, displacement - 1 shl mode
displacement_8bit:
compute displacement_size, 1
compute mod, 1
jump ready
index_only:
compute displacement_size, 4
compute mod, 0
jump ready
displacement_empty:
compute displacement_size, 0
compute mod, 0
ready:
exit
invalid_operand:
err 'invalid operand'
exit
invalid_address:
err 'invalid address'
exit
invalid_address_size:
err 'invalid address size'
exit
end calminstruction
end namespace
end iterate
iterate <instr,opcode,asize>, vpgatherdd,90h,4, vpgatherqd,91h,8, vgatherdps,92h,4, vgatherqps,93h,8
macro instr? dest*,src*,mask*
AVX.parse_operand@dest dest
AVX.parse_vsib_operand@src src
AVX.parse_operand@aux mask
if @dest.type = 'mmreg' & @src.type = 'mem' & @aux.type = 'mmreg'
if @src.size and not 4 | (@dest.size > 16 & @dest.size * (asize shr 2) > @src.visize) | (@src.visize > 16 & @dest.size * (asize shr 2) < @src.visize)
err 'invalid operand size'
else if @aux.size <> @dest.size
err 'operand sizes do not match'
else if @dest.rm = @aux.rm | @dest.rm = @src.index | @aux.rm = @src.index
err 'disallowed combination of registers'
end if
AVX.store_instruction@src @src.visize,VEX_66_0F38_W0,opcode,@dest.rm,@aux.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode,asize>, vpgatherdq,90h,4, vpgatherqq,91h,8, vgatherdpd,92h,4, vgatherqpd,93h,8
macro instr? dest*,src*,mask*
AVX.parse_operand@dest dest
AVX.parse_vsib_operand@src src
AVX.parse_operand@aux mask
if @dest.type = 'mmreg' & @src.type = 'mem' & @aux.type = 'mmreg'
if @src.size and not 8 | (@dest.size > 16 & @dest.size * (asize shr 2) > @src.visize * 2) | (@src.visize > 16 & @dest.size * (asize shr 2) < @src.visize * 2)
err 'invalid operand size'
else if @aux.size <> @dest.size
err 'operand sizes do not match'
else if @dest.rm = @aux.rm | @dest.rm = @src.index | @aux.rm = @src.index
err 'disallowed combination of registers'
end if
AVX.store_instruction@src @dest.size,VEX_66_0F38_W1,opcode,@dest.rm,@aux.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, packsswb,63h, packuswb,67h, packssdw,6Bh, paddb,0FCh, paddw,0FDh, paddd,0FEh, paddq,0D4h, paddsb,0ECh, paddsw,0EDh, paddusb,0DCh, paddusw,0DDh, \
pand,0DBh, pandn,0DFh, pavgb,0E0h, pavgw,0E3h, pcmpeqb,74h, pcmpeqw,75h, pcmpeqd,76h, pcmpgtb,64h, pcmpgtw,65h, pcmpgtd,66h, \
pmaddwd,0F5h, pmaxsw,0EEh, pmaxub,0DEh, pminsw,0EAh, pminub,0DAh, pmulhuw,0E4h, pmulhw,0E5h, pmullw,0D5h, pmuludq,0F4h, \
por,0EBh, psadbw,0F6h, psubb,0F8h, psubw,0F9h, psubd,0FAh, psubq,0FBh, psubsb,0E8h, psubsw,0E9h, psubusb,0D8h, psubusw,0D9h, \
punpckhbw,68h, punpckhwd,69h, punpckhdq,6Ah, punpckhqdq,6Dh, punpcklbw,60h, punpcklwd,61h, punpckldq,62h, punpcklqdq,6Ch, pxor,0EFh
macro v#instr? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F_W0,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, packusdw,2Bh, pcmpeqq,29h, pcmpgtq,37h, phaddw,1, phaddd,2, phaddsw,3, phsubw,5, phsubd,6, phsubsw,7, pmaddubsw,4, \
pmaxsb,3Ch, pmaxsd,3Dh, pmaxuw,3Eh, pmaxud,3Fh, pminsb,38h, pminsd,39h, pminuw,3Ah, pminud,3Bh, pmulhrsw,0Bh, pmulld,40h, pmuldq,28h, \
pshufb,0, psignb,8, psignw,9, psignd,0Ah
macro v#instr? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W0,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, mpsadbw,42h, palignr,0Fh, pblendd,02h
macro v#instr? dest*,src*,src2*,imm*
AVX.basic_instruction_imm8 VEX_66_0F3A_W0,opcode,0,dest,src,src2,imm
end macro
end iterate
iterate <instr,opcode>, pabsb,1Ch, pabsw,1Dh, pabsd,1Eh, pblendw,0Eh
macro v#instr? dest*,src*
AVX.single_source_instruction VEX_66_0F38_W0,opcode,0,dest,src
end macro
end iterate
iterate <instr,vex_mpw>, pshufd,VEX_66_0F_W0, pshufhw,VEX_F3_0F_W0, pshuflw,VEX_F2_0F_W0
macro v#instr? dest*,src*,imm*
AVX.single_source_instruction_imm8 vex_mpw,70h,0,dest,src,imm
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpsllvd,VEX_66_0F38_W0,47h, vpsllvq,VEX_66_0F38_W1,47h, vpsrlvd,VEX_66_0F38_W0,45h, vpsrlvq,VEX_66_0F38_W1,45h, vpsravd,VEX_66_0F38_W0,46h
macro instr? dest*,src*,src2*
AVX.basic_instruction vex_mpw,opcode,0,dest,src,src2
end macro
end iterate
macro vpblendvb? dest*,src*,src2*,mask*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
AVX.parse_operand@src2 src2
AVX.parse_operand@aux mask
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'mmreg'
if @src.size <> @dest.size | @src2.size and not @dest.size | @aux.size <> @dest.size
err 'operand sizes do not match'
end if
AVX.store_instruction@src2 @dest.size,VEX_66_0F3A_W0,4Ch,@dest.rm,@src.rm,1,(@aux.rm and 1111b) shl 4
else
err 'invalid combination of operands'
end if
end macro
macro vpmovmskb? dest*,src*
x86.parse_operand@dest dest
AVX.parse_operand@src src
if @dest.type = 'reg' & @src.type = 'mmreg'
if (@dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8))
err 'invalid operand size'
end if
AVX.store_instruction@src @src.size,VEX_66_0F_W0,0D7h,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,opcode,msize>, pmovsxbw,20h,8, pmovsxbd,21h,4, pmovsxbq,22h,2, pmovsxwd,23h,8, pmovsxwq,24h,4, pmovsxdq,25h,8, \
pmovzxbw,30h,8, pmovzxbd,31h,4, pmovzxbq,32h,2, pmovzxwd,33h,8, pmovzxwq,34h,4, pmovzxdq,35h,8
macro v#instr? dest*,src*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if (@src.type = 'mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not (msize * (@dest.size shr 4)))
err 'invalid operand size'
end if
AVX.store_instruction@src @dest.size,VEX_66_0F38_W0,opcode,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,postbyte>, pslldq,7, psrldq,3
macro v#instr dest*,src*,src2*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
x86.parse_operand@src2 src2
if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'imm'
if @src2.size and not 1
err 'invalid operand size'
else if @src.size <> @dest.size
err 'operand sizes do not match'
end if
AVX.store_instruction@src @dest.size,VEX_66_0F_W0,73h,postbyte,@dest.rm,1,@src2.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode_rrm,opcode,postbyte>, psllw,0F1h,71h,6, pslld,0F2h,72h,6, psllq,0F3h,73h,6, psraw,0E1h,71h,4, psrad,0E2h,72h,4, psrlw,0D1h,71h,2, psrld,0D2h,72h,2, psrlq,0D3h,73h,2
macro v#instr? dest*,src*,src2*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
AVX.parse_operand@src2 src2
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg')
if @src2.size and not 16
err 'invalid operand size'
else if @src.size <> @dest.size
err 'operand sizes do not match'
end if
AVX.store_instruction@src2 @dest.size,VEX_66_0F_W0,opcode_rrm,@dest.rm,@src.rm
else if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'imm'
if @src2.size and not 1
err 'invalid operand size'
else if @src.size <> @dest.size
err 'operand sizes do not match'
end if
AVX.store_instruction@src @dest.size,VEX_66_0F_W0,opcode,postbyte,@dest.rm,1,@src2.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro vmovntdqa? dest*,src*
AVX.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mem'
if @src.size and not @dest.size
err 'operand sizes do not match'
end if
AVX.store_instruction@src @dest.size,VEX_66_0F38_W0,2Ah,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,w>, vpmaskmovd,0, vpmaskmovq,1
macro instr? dest*,src*,src2*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
AVX.parse_operand@src2 src2
if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'mem'
if @src.size <> @dest.size | @src2.size and not @dest.size
err 'operand sizes do not match'
end if
AVX.store_instruction@src2 @dest.size,VEX_66_0F38_W#w,8Ch,@dest.rm,@src.rm
else if @dest.type = 'mem' & @src.type = 'mmreg' & @src2.type = 'mmreg'
if @src.size <> @src2.size | @dest.size and not @src.size
err 'operand sizes do not match'
end if
AVX.store_instruction@dest @src.size,VEX_66_0F38_W#w,8Eh,@src2.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro vbroadcasti128? dest*,src*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mem'
if @dest.size <> 32 | @src.size and not 16
err 'invalid operand size'
end if
AVX.store_instruction@src 32,VEX_66_0F38_W0,5Ah,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro vextracti128? dest*,src*,aux*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
x86.parse_operand@aux aux
if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm'
if @dest.size and not 16 | @src.size <> 32 | @aux.size and not 1
err 'invalid operand size'
end if
AVX.store_instruction@dest 32,VEX_66_0F3A_W0,39h,@src.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro vinserti128? dest*,src*,src2*,aux*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
AVX.parse_operand@src2 src2
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mmreg' | @src2.type = 'mem') & @aux.type = 'imm'
if @dest.size <> 32 | @src.size <> 32 | @src2.size and not 16 | @aux.size and not 1
err 'invalid operand size'
end if
AVX.store_instruction@src2 32,VEX_66_0F3A_W0,38h,@dest.rm,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro vperm2i128? dest*,src*,src2*,imm*
AVX.basic_instruction_imm8 VEX_66_0F3A_W0,46h,32,dest,src,src2,imm
end macro
iterate <instr,opcode,msize>, vbroadcastss,18h,4, vpbroadcastb,78h,1, vpbroadcastw,79h,2, vpbroadcastd,58h,4, vpbroadcastq,59h,8
macro instr? dest*,src*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem')
if (@src.type='mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not msize)
err 'invalid operand size'
end if
AVX.store_instruction@src @dest.size,VEX_66_0F38_W0,opcode,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro vbroadcastsd? dest*,src*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem')
if @dest.size <> 32 | (@src.type='mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not 8)
err 'invalid operand size'
end if
AVX.store_instruction@src 32,VEX_66_0F38_W0,19h,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,opcode>, vpermq,0, vpermpd,1
macro instr? dest*,src*,imm*
AVX.single_source_instruction_imm8 VEX_66_0F3A_W1,opcode,32,dest,src,imm
end macro
end iterate
iterate <instr,opcode>, vpermd,36h, vpermps,16h
macro instr? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W0,opcode,32,dest,src,src2
end macro
end iterate
end if

View File

@ -0,0 +1,10 @@
include 'avx512f.inc'
include 'avx512cd.inc'
include 'avx512vl.inc'
include 'avx512bw.inc'
include 'avx512dq.inc'
include 'avx512_ifma.inc'
include 'avx512_vbmi.inc'

View File

@ -0,0 +1,31 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,opcode>, vp4dpwssd,52h, vp4dpwssds,53h
macro instr? dest*,src*,src2*
AVX_512.parse_k1z_operand@dest dest
match rsrc+=3, src
AVX_512.parse_operand@src rsrc
else
AVX_512.parse_operand@src src
end match
AVX_512.parse_operand@src2 src2
if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'mem'
if @dest.size <> 64 | @src2.size and not 16
err 'invalid operand size'
else if @dest.size <> @src.size
err 'operand sizes do not match'
end if
@src2.memsize = 0
AVX_512.store_instruction@src2 @dest.size,VEX_F2_0F38_W0,EVEX_REQUIRED,opcode,@dest.mask,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate

View File

@ -0,0 +1,29 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,vex_mpw,opcode>, vpopcntb,VEX_66_0F38_W0,54h, vpopcntw,VEX_66_0F38_W1,54h
macro instr? dest*,src*
AVX_512.single_source_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src
end macro
end iterate
macro vpshufbitqmb? dest*,src*,src2*
AVX_512.parse_k1_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg')
if @src2.size and not @src.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src2 @src.size,VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,8Fh,@dest.mask,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,15 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,opcode>, vpmadd52luq,0B4h, vpmadd52huq,0B5h
macro instr? dest*,src*,src2*
AVX_512.basic_instruction_bcst VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2
end macro
end iterate

View File

@ -0,0 +1,22 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,vex_mpw,opcode>, vpermb,VEX_66_0F38_W0,8Dh, vpermi2b,VEX_66_0F38_W0,75h, vpermt2b,VEX_66_0F38_W0,7Dh
macro instr? dest*,src*,src2*
AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, vpmultishiftqb,83h
macro instr? dest*,src*,src2*
AVX_512.basic_instruction_bcst VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2
end macro
end iterate

View File

@ -0,0 +1,65 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,vex_mpw,opcode>, vpshldw,VEX_66_0F3A_W1,70h, vpshrdw,VEX_66_0F3A_W1,72h
macro instr? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_imm8 vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2,aux
end macro
end iterate
iterate <instr,unit,vex_mpw,opcode>, vpshldd,4,VEX_66_0F3A_W0,71h, vpshldq,8,VEX_66_0F3A_W1,71h, \
vpshrdd,4,VEX_66_0F3A_W0,73h, vpshrdq,8,VEX_66_0F3A_W1,73h
macro instr? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_bcst_imm8 vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src,src2,aux
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpshldvw,VEX_66_0F38_W1,70h, vpshrdvw,VEX_66_0F38_W1,72h
macro instr? dest*,src*,src2*
AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,unit,vex_mpw,opcode>, vpshldvd,4,VEX_66_0F38_W0,71h, vpshldvq,8,VEX_66_0F38_W1,71h, \
vpshrdvd,4,VEX_66_0F38_W0,73h, vpshrdvq,8,VEX_66_0F38_W1,73h
macro instr? dest*,src*,src2*
AVX_512.basic_instruction_bcst vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src,src2
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpcompressb,VEX_66_0F38_W0,63h, vpcompressw,VEX_66_0F38_W1,63h
macro instr? dest*,src*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg'
if @dest.size and not @src.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@dest @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpexpandb,VEX_66_0F38_W0,62h, vpexpandw,VEX_66_0F38_W1,62h
macro instr? dest*,src*
AVX_512.single_source_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src
end macro
end iterate

View File

@ -0,0 +1,14 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,opcode>, vpdpbusd,50h, vpdpbusds,51h, vpdpwssd,52h, vpdpwssds,53h
macro instr? dest*,src*,src2*
AVX_512.basic_instruction_bcst VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode,4,dest,src,src2
end macro
end iterate

View File

@ -0,0 +1,16 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,unit,vex_mpw,opcode>, vpopcntd,4,VEX_66_0F38_W0,55h, vpopcntq,8,VEX_66_0F38_W1,55h
macro instr? dest*,src*
AVX_512.single_source_instruction_bcst vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src
end macro
end iterate

View File

@ -0,0 +1,494 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <t,vex_mpw,msize>, d,VEX_66_0F_W1,4, q,VEX_0F_W1,8
iterate <instr,opcode>, kand,41h, kandn,42h, knot,44h, kor,45h, kxnor,46h, kxor,47h, kadd,4Ah
macro instr#t? dest*,src*,src2*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'maskreg' & @src.type = 'maskreg' & @src2.type = 'maskreg'
AVX.store_instruction@src2 32,vex_mpw,opcode,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, knot,44h, kortest,98h, ktest,99h
macro instr#t? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'maskreg' & @src.type = 'maskreg'
AVX.store_instruction@src 16,vex_mpw,opcode,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro kmov#t? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'maskreg' & (@src.type = 'maskreg' | @src.type = 'mem')
if @src.type = 'mem' & @src.size and not msize
err 'invalid operand size'
end if
AVX.store_instruction@src 16,vex_mpw,90h,@dest.rm
else if @dest.type = 'mem' & @src.type = 'maskreg'
if @dest.size and not msize
err 'invalid operand size'
end if
AVX.store_instruction@dest 16,vex_mpw,91h,@src.rm
else if @dest.type = 'maskreg' & @src.type = 'reg'
if (msize < 8 & @src.size <> 4) | (msize = 8 & @src.size <> 8)
err 'invalid operand size'
else if msize = 8 & x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src 16,vex_mpw,92h,@dest.rm
else if @dest.type = 'reg' & @src.type = 'maskreg'
if (msize < 8 & @dest.size <> 4) | (msize = 8 & @dest.size <> 8)
err 'invalid operand size'
else if msize = 8 & x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src 16,vex_mpw,93h,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, kshiftrd,VEX_66_0F3A_W0,31h, kshiftrq,VEX_66_0F3A_W1,31h, \
kshiftld,VEX_66_0F3A_W0,33h, kshiftlq,VEX_66_0F3A_W1,33h
macro instr? dest*,src*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if @dest.type = 'maskreg' & @src.type = 'maskreg' & @aux.type = 'imm'
if @aux.size and not 1
err 'invalid operand size'
end if
AVX.store_instruction@src 16,vex_mpw,opcode,@dest.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw>, kunpckwd,VEX_0F_W0, kunpckdq,VEX_0F_W1
macro instr? dest*,src*,src2*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'maskreg' & @src.type = 'maskreg' & @src2.type = 'maskreg'
AVX.store_instruction@src2 32,vex_mpw,4Bh,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,evex_f,opcode_rm,opcode_mr>, vmovdqu8,VEX_F2_0F_W0,EVEX_REQUIRED+EVEX_VL,6Fh,7Fh, vmovdqu16,VEX_F2_0F_W1,EVEX_REQUIRED+EVEX_VL,6Fh,7Fh
macro instr? dest*,src*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem')
if @src.size and not @dest.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src @dest.size,vex_mpw,evex_f,opcode_rm,@dest.mask,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
if @dest.size and not @src.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@dest @src.size,vex_mpw,evex_f,opcode_mr,@dest.mask,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, vpabsb,1Ch, vpabsw,1Dh
macro instr? dest*,src*
AVX_512.single_source_instruction VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,dest,src
end macro
end iterate
iterate <instr,opcode>, vpacksswb,63h, vpackuswb,67h, vpaddb,0FCh, vpaddw,0FDh, vpaddsb,0ECh, vpaddsw,0EDh, vpaddusb,0DCh, vpaddusw,0DDh, vpavgb,0E0h, vpavgw,0E3h, \
vpmaddwd,0F5h, vpmaxsw,0EEh, vpmaxub,0DEh, vpminsw,0EAh, vpminub,0DAh, vpmulhuw,0E4h, vpmulhw,0E5h, vpmullw,0D5h, \
vpsadbw,0F6h, vpsubb,0F8h, vpsubw,0F9h, vpsubsb,0E8h, vpsubsw,0E9h, vpsubusb,0D8h, vpsubusw,0D9h, \
vpunpckhbw,68h, vpunpckhwd,69h, vpunpcklbw,60h, vpunpcklwd,61h
macro instr? dest*,src*,src2*
AVX_512.basic_instruction VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, vpackssdw,6Bh
macro instr? dest*,src*,src2*
AVX_512.basic_instruction_bcst VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, vpackusdw,2Bh
macro instr? dest*,src*,src2*
AVX_512.basic_instruction_bcst VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, vpalignr,0Fh
macro instr? dest*,src*,src2*,imm*
AVX_512.basic_instruction_imm8 VEX_66_0F3A_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,dest,src,src2,imm
end macro
end iterate
iterate <instr,opcode>, vpmaddubsw,4, vpmaxsb,3Ch, vpmaxuw,3Eh, vpminsb,38h, vpminuw,3Ah, vpmulhrsw,0Bh, vpshufb,0
macro instr? dest*,src*,src2*
AVX_512.basic_instruction VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, vpcmpeqb,74h, vpcmpeqw,75h, vpcmpgtb,64h, vpcmpgtw,65h
macro instr? dest*,src*,src2*
AVX_512.parse_k1_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg')
if @src2.size and not @src.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src2 @src.size,VEX_66_0F_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm
else if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg')
if @src.size <> @dest.size | @src2.size and not @dest.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src2 @src.size,VEX_66_0F_W0,EVEX_FORBIDDEN,opcode,@dest.mask,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro vpextrb? dest*,src*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm'
if (@dest.type = 'reg' & @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | (@dest.type = 'mem' & @dest.size and not 1) | @src.size <> 16 | @aux.size and not 1
err 'invalid operand size'
end if
@dest.memsize = 1
AVX_512.store_instruction@dest 16,VEX_66_0F3A_W0,EVEX_AS_VEX,14h,0,@src.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro vpextrw? dest*,src*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm'
if @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8) | @src.size <> 16 | @aux.size and not 1
err 'invalid operand size'
end if
AVX_512.store_instruction@src 16,VEX_66_0F_W0,EVEX_AS_VEX,0C5h,0,@dest.rm,,1,@aux.imm
else if @dest.type = 'mem' & @src.type = 'mmreg' & @aux.type = 'imm'
if @dest.size and not 2 | @src.size <> 16 | @aux.size and not 1
err 'invalid operand size'
end if
@dest.memsize = 2
AVX_512.store_instruction@dest 16,VEX_66_0F3A_W0,EVEX_AS_VEX,15h,0,@src.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,vex_mpw,opcode,msize>, vpinsrb,VEX_66_0F3A_W0,20h,1, vpinsrw,VEX_66_0F_W0,0C4h,2
macro instr? dest*,src*,src2*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'reg' | @src2.type = 'mem') & @aux.type = 'imm'
if @dest.size <> 16 | @src.size <> 16 | (@src2.type = 'reg' & @src2.size <> 4) | (@src2.type = 'mem' & @src2.size and not msize) | @aux.size and not 1
err 'invalid operand size'
end if
@src2.memsize = msize
AVX_512.store_instruction@src2 16,vex_mpw,EVEX_AS_VEX,opcode,0,@dest.rm,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode,msize>, vpmovsxbw,20h,8, vpmovzxbw,30h,8
macro instr? dest*,src*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
@src.memsize = msize * (@dest.size shr 4)
if (@src.type = 'mmreg' & @src.size <> (@src.memsize-1) and not 15 + 16) | (@src.type = 'mem' & @src.size and not @src.memsize)
err 'invalid operand size'
end if
AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,@dest.mask,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw>, vpshufhw,VEX_F3_0F_W0, vpshuflw,VEX_F2_0F_W0
macro instr? dest*,src*,aux*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'
if @aux.size and not 1
err 'invalid operand size'
else if @src.size and not @dest.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_AS_VEX+EVEX_VL,70h,@dest.mask,@dest.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,postbyte>, vpslldq,7, vpsrldq,3
macro instr? dest*,src*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') & @aux.type = 'imm'
if @aux.size and not 1
err 'invalid operand size'
else if @src.size <> @dest.size
err 'operand sizes do not match'
end if
if @src.type = 'mem'
AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_REQUIRED+EVEX_VL,73h,0,postbyte,@dest.rm,1,@aux.imm
else
AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,73h,0,postbyte,@dest.rm,1,@aux.imm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode_rrm,opcode,postbyte>, vpsllw,0F1h,71h,6, vpsraw,0E1h,71h,4, vpsrlw,0D1h,71h,2
macro instr? dest*,src*,src2*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg')
@src2.memsize = 16
if @src2.size and not @src2.memsize
err 'invalid operand size'
else if @src.size <> @dest.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src2 @dest.size,VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode_rrm,@dest.mask,@dest.rm,@src.rm
else if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') & @src2.type = 'imm'
if @src2.size and not 1
err 'invalid operand size'
else if @src.size <> @dest.size
err 'operand sizes do not match'
end if
if @src.type = 'mem'
AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,postbyte,@dest.rm,1,@src2.imm
else
AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,@dest.mask,postbyte,@dest.rm,1,@src2.imm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vdbpsadbw,VEX_66_0F3A_W0,42h
macro instr? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_imm8 vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2,aux
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpblendmb,VEX_66_0F38_W0,66h, vpblendmw,VEX_66_0F38_W1,66h
macro instr? dest*,src*,src2*&
AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode,opcode_g,msize>, vpbroadcastb,78h,7Ah,1, vpbroadcastw,79h,7Bh,2
macro instr? dest*,src*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem')
if (@src.type='mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not msize)
err 'invalid operand size'
end if
@src.memsize = msize
AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,@dest.mask,@dest.rm
else if @dest.type = 'mmreg' & @src.type = 'reg'
if @src.size <> msize & (@src.size <> 4 | msize = 8)
err 'invalid operand size'
end if
@src.memsize = msize
if msize = 8
AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode_g,@dest.mask,@dest.rm
else
AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode_g,@dest.mask,@dest.rm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpcmpb,VEX_66_0F3A_W0,3Fh, vpcmpub,VEX_66_0F3A_W0,3Eh, vpcmpw,VEX_66_0F3A_W1,3Fh, vpcmpuw,VEX_66_0F3A_W1,3Eh
macro instr? dest*,src*,src2*,aux*
AVX_512.parse_k1_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
x86.parse_operand@aux aux
if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm'
if @src2.size and not @src.size | @aux.size and not 1
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src2 @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpermw,VEX_66_0F38_W1,8Dh, vpermi2w,VEX_66_0F38_W1,75h, vpermt2w,VEX_66_0F38_W1,7Dh
macro instr? dest*,src*,src2*
AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpmovb2m,VEX_F3_0F38_W0,29h, vpmovw2m,VEX_F3_0F38_W1,29h
macro instr? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'maskreg' & @src.type = 'mmreg'
AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpmovm2b,VEX_F3_0F38_W0,28h, vpmovm2w,VEX_F3_0F38_W1,28h
macro instr? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'maskreg'
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ratio,opcode>, vpmovuswb,2,10h, vpmovswb,2,20h, vpmovwb,2,30h
macro instr? dest*,src*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg'
@dest.memsize = @src.size / ratio
if (@dest.type = 'mmreg' & @dest.size <> (@dest.memsize-1) and not 15 + 16) | (@dest.type = 'mem' & @dest.size and not @dest.memsize)
err 'invalid operand size'
end if
AVX_512.store_instruction@dest @src.size,VEX_F3_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, vpsllvw,12h, vpsrlvw,10h, vpsravw,11h
macro instr? dest*,src*,src2*
AVX_512.basic_instruction VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vptestnmb,VEX_F3_0F38_W0,26h, vptestnmw,VEX_F3_0F38_W1,26h, vptestmb,VEX_66_0F38_W0,26h, vptestmw,VEX_66_0F38_W1,26h
macro instr? dest*,src*,src2*
AVX_512.parse_k1_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg')
if @src2.size and not @src.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src2 @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate

View File

@ -0,0 +1,29 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,vex_mpw,opcode>, vpbroadcastmb2q,VEX_F3_0F38_W1,2Ah, vpbroadcastmw2d,VEX_F3_0F38_W0,3Ah
macro instr? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'maskreg'
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,unit,vex_mpw,opcode>, vpconflictd,4,VEX_66_0F38_W0,0C4h, vpconflictq,8,VEX_66_0F38_W1,0C4h, vplzcntd,4,VEX_66_0F38_W0,44h, vplzcntq,8,VEX_66_0F38_W1,44h
macro instr? dest*,src*&
AVX_512.single_source_instruction_bcst vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src
end macro
end iterate

View File

@ -0,0 +1,463 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,opcode>, kandb,41h, kandnb,42h, knotb,44h, korb,45h, kxnorb,46h, kxorb,47h, kaddb,4Ah
macro instr? dest*,src*,src2*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'maskreg' & @src.type = 'maskreg' & @src2.type = 'maskreg'
AVX.store_instruction@src2 32,VEX_66_0F_W0,opcode,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, knotb,44h, kortestb,98h, ktestb,99h
macro instr? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'maskreg' & @src.type = 'maskreg'
AVX.store_instruction@src 16,VEX_66_0F_W0,opcode,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro kmovb? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'maskreg' & (@src.type = 'maskreg' | @src.type = 'mem')
if @src.type = 'mem' & @src.size and not 1
err 'invalid operand size'
end if
AVX.store_instruction@src 16,VEX_66_0F_W0,90h,@dest.rm
else if @dest.type = 'mem' & @src.type = 'maskreg'
if @dest.size and not 1
err 'invalid operand size'
end if
AVX.store_instruction@dest 16,VEX_66_0F_W0,91h,@src.rm
else if @dest.type = 'maskreg' & @src.type = 'reg'
if @src.size <> 4
err 'invalid operand size'
end if
AVX.store_instruction@src 16,VEX_66_0F_W0,92h,@dest.rm
else if @dest.type = 'reg' & @src.type = 'maskreg'
if @dest.size <> 4
err 'invalid operand size'
end if
AVX.store_instruction@src 16,VEX_66_0F_W0,93h,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro kaddw? dest*,src*,src2*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'maskreg' & @src.type = 'maskreg' & @src2.type = 'maskreg'
AVX.store_instruction@src2 32,VEX_0F_W0,opcode,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
macro ktestw? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'maskreg' & @src.type = 'maskreg'
AVX.store_instruction@src 16,VEX_0F_W0,opcode,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,vex_mpw,opcode>, kshiftrb,VEX_66_0F3A_W0,30h, kshiftlb,VEX_66_0F3A_W0,32h
macro instr? dest*,src*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if @dest.type = 'maskreg' & @src.type = 'maskreg' & @aux.type = 'imm'
if @aux.size and not 1
err 'invalid operand size'
end if
AVX.store_instruction@src 16,vex_mpw,opcode,@dest.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, and,54h, andn,55h, or,56h, xor,57h
macro v#instr#pd? dest*,src*,src2*&
AVX_512.basic_instruction_bcst VEX_66_0F_W0,EVEX_W1+EVEX_VL,opcode,8,dest,src,src2
end macro
macro v#instr#ps? dest*,src*,src2*&
AVX_512.basic_instruction_bcst VEX_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, vbroadcastf32x2,19h, vbroadcasti32x2,59h
macro instr? dest*,src*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem')
if @dest.size = 16 | (@src.type = 'mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not 8)
err 'invalid operand size'
end if
@src.memsize = 8
AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode,msize>, vbroadcastf32x8,VEX_66_0F38_W0,1Bh,32, vbroadcastf64x2,VEX_66_0F38_W1,1Ah,16, \
vbroadcasti32x8,VEX_66_0F38_W0,5Bh,32, vbroadcasti64x2,VEX_66_0F38_W1,5Ah,16
macro instr? dest*,src*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mem'
if @dest.size <= msize | @src.size and not msize
err 'invalid operand size'
end if
@src.memsize = msize
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vcvtpd2qq,VEX_66_0F_W1,7Bh, vcvtpd2uqq,VEX_66_0F_W1,79h, \
vcvtqq2pd,VEX_F3_0F_W1,0E6h, vcvtuqq2pd,VEX_F3_0F_W1,7Ah
macro instr? dest*,src*&
AVX_512.single_source_instruction_bcst_er vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vcvttpd2qq,VEX_66_0F_W1,7Ah, vcvttpd2uqq,VEX_66_0F_W1,78h
macro instr? dest*,src*&
AVX_512.single_source_instruction_bcst_sae vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vcvtps2qq,VEX_66_0F_W0,7Bh, vcvtps2uqq,VEX_66_0F_W0,79h
macro instr? dest*,src_er*&
AVX_512.parse_k1z_operand@dest dest
match src=,er, src_er
AVX_512.parse_operand@src src
AVX_512.parse_er@src er,32
else
AVX_512.parse_bcst_operand@src src_er,4
end match
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if (@src.type = 'mem' & @src.size and not (@dest.size shr 1)) | (@src.type = 'mmreg' & (@dest.size shr 1 - 1) and not 15 + 16 <> @src.size)
err 'invalid operand size'
end if
if @src.memsize = 0
@src.memsize = @dest.size shr 1
end if
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vcvtqq2ps,VEX_0F_W1,5Bh, vcvtuqq2ps,VEX_F2_0F_W1,7Ah
macro instr? dest*,src_er*&
AVX_512.parse_k1z_operand@dest dest
match src=,er, src_er
AVX_512.parse_operand@src src
AVX_512.parse_er@src er
else
AVX_512.parse_bcst_operand@src src_er,8
end match
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @src.size = 0
if @dest.size = 16
err 'operand size not specified'
else
@src.size = 64
end if
end if
if (@src.size shr 1 - 1) and not 15 + 16 <> @dest.size | @src.size > 64
err 'invalid operand size'
end if
AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vcvttps2qq,VEX_66_0F_W0,7Ah, vcvttps2uqq,VEX_66_0F_W0,78h
macro instr? dest*,src_sae*&
AVX_512.parse_k1z_operand@dest dest
match src=,sae, src_sae
AVX_512.parse_operand@src src
AVX_512.parse_sae @src,sae
else
AVX_512.parse_bcst_operand@src src_sae,4
end match
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if (@src.type = 'mem' & @src.size and not (@dest.size shr 1)) | (@src.type = 'mmreg' & (@dest.size shr 1 - 1) and not 15 + 16 <> @src.size)
err 'invalid operand size'
end if
if @src.memsize = 0
@src.memsize = @dest.size shr 1
end if
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode,msize>, vextractf32x8,VEX_66_0F3A_W0,1Bh,32, vextractf64x2,VEX_66_0F3A_W1,19h,16, \
vextracti32x8,VEX_66_0F3A_W0,3Bh,32, vextracti64x2,VEX_66_0F3A_W1,39h,16
macro instr? dest*,src*,aux*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm'
if @dest.size and not msize | @src.size <= msize | @aux.size and not 1
err 'invalid operand size'
end if
@dest.memsize = msize
AVX_512.store_instruction@dest @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@src.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode,msize>, vinsertf32x8,VEX_66_0F3A_W0,1Ah,32, vinsertf64x2,VEX_66_0F3A_W1,18h,16, \
vinserti32x8,VEX_66_0F3A_W0,3Ah,32, vinserti64x2,VEX_66_0F3A_W1,38h,16
macro instr? dest*,src*,src2*,aux*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mmreg' | @src2.type = 'mem') & @aux.type = 'imm'
if @dest.size <= msize | @src.size <= msize | @src2.size and not msize | @aux.size and not 1
err 'invalid operand size'
end if
@src2.memsize = msize
AVX_512.store_instruction@src2 @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,unit,vex_mpw>, vfpclasspd,8,VEX_66_0F3A_W1, vfpclassps,4,VEX_66_0F3A_W0
macro instr? dest*,src*,aux*
AVX_512.parse_k1_operand@dest dest
AVX_512.parse_bcst_operand@src src,unit
x86.parse_operand@aux aux
if @dest.type = 'maskreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'
if @src.size = 0
err 'operand size not specified'
else if (@src.size <> 16 & @src.size <> 32 & @src.size <> 64) | @aux.size and not 1
err 'invalid operand size'
end if
AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,66h,@dest.mask,@dest.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,unit,vex_mpw>, vfpclasssd,8,VEX_66_0F3A_W1, vfpclassss,4,VEX_66_0F3A_W0
macro instr? dest*,src*,aux*
AVX_512.parse_k1_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if @dest.type = 'maskreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'
if (@src.type = 'mem' & @src.size and not unit) | (@src.type = 'mmreg' & @src.size <> 16) | @aux.size and not 1
err 'invalid operand size'
end if
@src.memsize = 16
AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED,67h,@dest.mask,@dest.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro vpextrd? dest*,src*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm'
if (@dest.type = 'reg' & @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | (@dest.type = 'mem' & @dest.size and not 4) | @src.size <> 16 | @aux.size and not 1
err 'invalid operand size'
end if
@dest.memsize = 4
AVX_512.store_instruction@dest 16,VEX_66_0F3A_W0,EVEX_AS_VEX,16h,0,@src.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro vpinsrd? dest*,src*,src2*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'reg' | @src2.type = 'mem') & @aux.type = 'imm'
if @dest.size <> 16 | @src.size <> 16 | (@src2.type = 'reg' & @src2.size <> 4) | (@src2.type = 'mem' & @src2.size and not 4) | @aux.size and not 1
err 'invalid operand size'
end if
@src2.memsize = 4
AVX_512.store_instruction@src2 16,VEX_66_0F3A_W0,EVEX_AS_VEX,22h,0,@dest.rm,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro vpextrq? dest*,src*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm'
if @dest.size and not 8 | @src.size <> 16 | @aux.size and not 1
err 'invalid operand size'
end if
if x86.mode < 64
err 'instruction requires long mode'
end if
@dest.memsize = 8
AVX_512.store_instruction@dest 16,VEX_66_0F3A_W1,EVEX_AS_VEX,16h,0,@src.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro vpinsrq? dest*,src*,src2*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@src2 src2
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'reg' | @src2.type = 'mem') & @aux.type = 'imm'
if @dest.size <> 16 | @src.size <> 16 | @src2.size and not 8 | @aux.size and not 1
err 'invalid operand size'
end if
if x86.mode < 64
err 'instruction requires long mode'
end if
@src2.memsize = 8
AVX_512.store_instruction@src2 16,VEX_66_0F3A_W1,EVEX_AS_VEX,22h,0,@dest.rm,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro vpmullq? dest*,src*,src2*
AVX_512.basic_instruction_bcst VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,40h,8,dest,src,src2
end macro
iterate <instr,vex_mpw,opcode>, vpmovm2d,VEX_F3_0F38_W0,38h, vpmovm2q,VEX_F3_0F38_W1,38h
macro instr? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'maskreg'
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpmovd2m,VEX_F3_0F38_W0,39h, vpmovq2m,VEX_F3_0F38_W1,39h
macro instr? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'maskreg' & @src.type = 'mmreg'
AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, range,50h
macro v#instr#pd? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_bcst_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2,aux
end macro
macro v#instr#ps? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_bcst_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED+EVEX_VL,opcode,4,dest,src,src2,aux
end macro
macro v#instr#sd? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED,opcode+1,8,dest,src,src2,aux
end macro
macro v#instr#ss? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED,opcode+1,4,dest,src,src2,aux
end macro
end iterate
macro vreducepd? dest*,src*,aux*&
AVX_512.single_source_instruction_bcst_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED+EVEX_VL,56h,8,dest,src,aux
end macro
macro vreduceps? dest*,src*,aux*&
AVX_512.single_source_instruction_bcst_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED+EVEX_VL,56h,4,dest,src,aux
end macro
macro vreducesd? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED,57h,8,dest,src,src2,aux
end macro
macro vreducess? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED,57h,4,dest,src,src2,aux
end macro

View File

@ -0,0 +1,39 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,unit,vex_mpw,opcode>, vexp2ps,4,VEX_66_0F38_W0,0C8h, vexp2pd,4,VEX_66_0F38_W1,0C8h, \
vrcp28ps,4,VEX_66_0F38_W0,0CAh, vrcp28pd,8,VEX_66_0F38_W1,0CAh, vrsqrt28ps,4,VEX_66_0F38_W0,0CCh, vrsqrt28pd,8,VEX_66_0F38_W1,0CCh
macro instr? dest*,src_sae*&
AVX_512.parse_k1z_operand@dest dest
match src=,sae, src_sae
AVX_512.parse_operand@src src
AVX_512.parse_sae@src sae
else
AVX_512.parse_bcst_operand@src src_sae,unit
end match
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 64
err 'invalid operand size'
else if @src.size and not @dest.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED,opcode,@dest.mask,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,unit,vex_mpw,opcode>, vrcp28ss,4,VEX_66_0F38_W0,0CBh, vrcp28sd,8,VEX_66_0F38_W1,0CBh, vrsqrt28ss,4,VEX_66_0F38_W0,0CDh, vrsqrt28sd,8,VEX_66_0F38_W1,0CDh
macro instr? dest*,src*,src2*&
AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED,opcode,unit,dest,src,src2
end macro
end iterate

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,postbyte>, gatherpf0,1 ,gatherpf1,2 ,scatterpf0,5, scatterpf1,6
macro v#instr#dps? src*
AVX_512.parse_k1_vsib_operand@src src
if @src.type = 'mem' & @src.mask
if @src.size and not 4 | @src.visize <> 64
err 'invalid operand size'
end if
@src.memsize = 4
AVX_512.store_instruction@src 64,VEX_66_0F38_W0,EVEX_REQUIRED,0C6h,@src.mask,postbyte,@src.index and 10000b
else
err 'invalid combination of operands'
end if
end macro
macro v#instr#qps? src*
AVX_512.parse_k1_vsib_operand@src src
if @src.type = 'mem' & @src.mask
if @src.size and not 8 | @src.visize <> 64
err 'invalid operand size'
end if
@src.memsize = 4
AVX_512.store_instruction@src 64,VEX_66_0F38_W0,EVEX_REQUIRED,0C7h,@src.mask,postbyte,@src.index and 10000b
else
err 'invalid combination of operands'
end if
end macro
macro v#instr#dpd? src*
AVX_512.parse_k1_vsib_operand@src src
if @src.type = 'mem' & @src.mask
if @src.size and not 4 | @src.visize <> 32
err 'invalid operand size'
end if
@src.memsize = 8
AVX_512.store_instruction@src 64,VEX_66_0F38_W1,EVEX_REQUIRED,0C6h,@src.mask,postbyte,@src.index and 10000b
else
err 'invalid combination of operands'
end if
end macro
macro v#instr#qpd? src*
AVX_512.parse_k1_vsib_operand@src src
if @src.type = 'mem' & @src.mask
if @src.size and not 8 | @src.visize <> 64
err 'invalid operand size'
end if
@src.memsize = 8
AVX_512.store_instruction@src 64,VEX_66_0F38_W1,EVEX_REQUIRED,0C7h,@src.mask,postbyte,@src.index and 10000b
else
err 'invalid combination of operands'
end if
end macro
end iterate

View File

@ -0,0 +1,8 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
AVX512VL = 1

View File

@ -0,0 +1,97 @@
include 'avx.inc'
macro andn? dest*,src*,src2*
x86.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@src2 src2
if @dest.type = 'reg' & @src.type = 'reg' & (@src2.type = 'mem' | @src2.type = 'reg')
if @dest.size < 4
err 'invalid operand size'
else if @src.size <> @dest.size | @src2.size and not @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8
if x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src2 16,VEX_0F38_W1,0F2h,@dest.rm,@src.rm
else
AVX.store_instruction@src2 16,VEX_0F38_W0,0F2h,@dest.rm,@src.rm
end if
else
err 'invalid combination of operands'
end if
end macro
macro bextr? dest*,src*,src2*
x86.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@src2 src2
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') & @src2.type = 'reg'
if @dest.size < 4
err 'invalid operand size'
else if @src.size and not @dest.size | @src2.size <> @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8
if x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src 16,VEX_0F38_W1,0F7h,@dest.rm,@src2.rm
else
AVX.store_instruction@src 16,VEX_0F38_W0,0F7h,@dest.rm,@src2.rm
end if
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,opcode,postbyte>, blsi,0F3h,3, blsmsk,0F3h,2, blsr,0F3h,1
macro instr? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg')
if @dest.size < 4
err 'invalid operand size'
else if @src.size and not @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8
if x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src 16,VEX_0F38_W1,opcode,postbyte,@dest.rm
else
AVX.store_instruction@src 16,VEX_0F38_W0,opcode,postbyte,@dest.rm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, lzcnt,0BDh, tzcnt,0BCh
macro instr? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & ( @src.type = 'reg' | @src.type = 'mem' )
if @src.size and not @dest.size
err 'operand sizes do not match'
end if
@src.opcode_prefix = 0F3h
if @dest.size > 1
x86.select_operand_prefix@src @dest.size
x86.store_instruction@src <0Fh,opcode>,@dest.rm
else
err 'invalid operand size'
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate

View File

@ -0,0 +1,106 @@
include 'bmi1.inc'
iterate <instr,opcode>, bzhi,0F5h
macro instr? dest*,src*,src2*
x86.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@src2 src2
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') & @src2.type = 'reg'
if @dest.size < 4
err 'invalid operand size'
else if @src.size and not @dest.size | @src2.size <> @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8
if x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src 16,VEX_0F38_W1,opcode,@dest.rm,@src2.rm
else
AVX.store_instruction@src 16,VEX_0F38_W0,opcode,@dest.rm,@src2.rm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mp,opcode>, mulx,VEX_F2_0F38,0F6h, pdep,VEX_F2_0F38,0F5h, pext,VEX_F3_0F38,0F5h
macro instr? dest*,src*,src2*
x86.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@src2 src2
if @dest.type = 'reg' & @src.type = 'reg' & (@src2.type = 'mem' | @src2.type = 'reg')
if @dest.size < 4
err 'invalid operand size'
else if @src.size <> @dest.size | @src2.size and not @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8
if x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src2 16,vex_mp#_W1,opcode,@dest.rm,@src.rm
else
AVX.store_instruction@src2 16,vex_mp#_W0,opcode,@dest.rm,@src.rm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro rorx? dest*,src*,src2*
x86.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@src2 src2
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') & @src2.type = 'imm'
if @dest.size < 4 | @src2.size and not 1
err 'invalid operand size'
else if @src.size and not @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8
if x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src 16,VEX_F2_0F3A_W1,0F0h,@dest.rm,,1,@src2.imm
else
AVX.store_instruction@src 16,VEX_F2_0F3A_W0,0F0h,@dest.rm,,1,@src2.imm
end if
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,vex_mp,opcode>, sarx,VEX_F3_0F38,0F7h, shlx,VEX_66_0F38,0F7h, shrx,VEX_F2_0F38,0F7h
macro instr? dest*,src*,src2*
x86.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@src2 src2
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') & @src2.type = 'reg'
if @dest.size < 4
err 'invalid operand size'
else if @src.size and not @dest.size | @src2.size <> @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8
if x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src 16,vex_mp#_W1,opcode,@dest.rm,@src2.rm
else
AVX.store_instruction@src 16,vex_mp#_W0,opcode,@dest.rm,@src2.rm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate

View File

@ -0,0 +1,8 @@
iterate <instr,modrm>, endbr32,0FBh, endbr64,0FAh
macro instr?
db 0F3h,0Fh,1Eh,modrm
end macro
end iterate

View File

@ -0,0 +1,106 @@
iterate <instr,ext,postbyte>, clrssbsy,0AEh,6, rstorssp,01h,5
macro instr? src*
x86.parse_operand@src src
if @src.type = 'mem'
if @src.size and not 8
err 'invalid operand size'
else
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,ext>,postbyte
end if
else
err 'invalid operand'
end if
end macro
end iterate
iterate <instr,ext,postbyte>, incsspd,0AEh,5, rdsspd,1Eh,1
macro instr? src*
x86.parse_operand@src src
if @src.type = 'reg'
if @src.size <> 4
err 'invalid operand size'
else
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,ext>,postbyte
end if
else
err 'invalid operand'
end if
end macro
end iterate
iterate <instr,ext,postbyte>, incsspq,0AEh,5, rdsspq,1Eh,1
macro instr? src*
x86.parse_operand@src src
if @src.type = 'reg'
if @src.size <> 8
err 'invalid operand size'
else
x86.select_operand_prefix@src 8
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,ext>,postbyte
end if
else
err 'invalid operand'
end if
end macro
end iterate
iterate <instr,modrm>, saveprevssp,0EAh, setssbsy,0E8h
macro instr?
db 0F3h,0Fh,01h,modrm
end macro
end iterate
iterate <instr,prefix,ext>, wrssd,0,0F6h, wrussd,66h,0F5h
macro instr? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
local size
if @src.size <> 4
err 'invalid operand size'
else if @dest.size and not @src.size
err 'operand sizes do not match'
end if
if @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' )
@dest.opcode_prefix = prefix
x86.store_instruction@dest <0Fh,38h,ext>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,prefix,ext>, wrssq,0,0F6h, wrussq,66h,0F5h
macro instr? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
local size
if @src.size <> 8
err 'invalid operand size'
else if @dest.size and not @src.size
err 'operand sizes do not match'
end if
if @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' )
x86.select_operand_prefix@dest 8
@dest.opcode_prefix = prefix
x86.store_instruction@dest <0Fh,38h,ext>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate

View File

@ -0,0 +1,29 @@
include 'avx.inc'
macro vcvtph2ps? dest*,src*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem')
if (@src.type = 'mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size*2 <> @dest.size)
err 'invalid operand size'
end if
AVX.store_instruction@src @dest.size,VEX_66_0F38_W0,13h,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro vcvtps2ph? dest*,src*,round*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
x86.parse_operand@aux round
if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm'
if (@dest.type = 'mmreg' & @dest.size <> 16) | (@dest.type = 'mem' & @dest.size*2 <> @src.size) | @aux.size and not 1
err 'invalid operand size'
end if
AVX.store_instruction@dest @src.size,VEX_66_0F3A_W0,1Dh,@src.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,30 @@
include 'avx.inc'
iterate <instr,lcode>, vfmaddsub,6, vfmsubadd,7, vfmadd,8, vfmsub,0Ah, vfnmadd,0Ch, vfnmsub,0Eh
iterate <order,hcode>, 132,90h, 213,0A0h, 231,0B0h
macro instr#order#pd? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W1,hcode+lcode,0,dest,src,src2
end macro
macro instr#order#ps? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W0,hcode+lcode,0,dest,src,src2
end macro
if lcode > 7
macro instr#order#sd? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W1,hcode+lcode+1,8,dest,src,src2
end macro
macro instr#order#ss? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W0,hcode+lcode+1,4,dest,src,src2
end macro
end if
end iterate
end iterate

View File

@ -0,0 +1,24 @@
iterate <instr,postbyte>, rdfsbase,0, rdgsbase,1, wrfsbase,2, wrgsbase,3
macro instr? dest*
if x86.mode = 64
x86.parse_operand@dest dest
if @dest.type = 'reg'
if @dest.size >= 4
@dest.opcode_prefix = 0F3h
x86.select_operand_prefix@dest @dest.size
x86.store_instruction@dest <0Fh,0AEh>,postbyte
else
err 'invalid operand size'
end if
else
err 'invalid operand'
end if
else
err 'instruction requires long mode'
end if
end macro
end iterate

View File

@ -0,0 +1,53 @@
include 'sse.inc'
iterate <instr,supp>, gf2p8mulb,0CFh
macro instr? dest*,src*
SSE.basic_instruction 66h,<38h,supp>,16,dest,src
end macro
end iterate
iterate <instr,supp>, gf2p8affineinvqb,0CFh, gf2p8affineqb,0CEh
macro instr? dest*,src*,imm*
SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm
end macro
end iterate
if defined AVX_512
iterate <instr,opcode>, gf2p8mulb,0CFh
macro v#instr? dest*,src*,src2*&
AVX_512.basic_instruction VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, gf2p8affineinvqb,0CFh, gf2p8affineqb,0CEh
macro v#instr? dest*,src*,src2*,imm*&
AVX_512.basic_instruction_bcst_imm8 VEX_66_0F3A_W1,EVEX_W1+EVEX_VL,opcode,8,dest,src,src2,imm
end macro
end iterate
else if defined AVX
iterate <instr,opcode>, gf2p8mulb,0CFh
macro v#instr? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W0,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, gf2p8affineinvqb,0CFh, gf2p8affineqb,0CEh
macro v#instr? dest*,src*,src2*,imm*
AVX.basic_instruction_imm8 VEX_66_0F3A_W1,opcode,0,dest,src,src2,imm
end macro
end iterate
end if

View File

@ -0,0 +1,16 @@
macro xacquire? instr&
db 0F2h
instr
end macro
macro xrelease? instr&
db 0F3h
instr
end macro
macro xtest?
db 0Fh,1,0D6h
end macro

View File

@ -0,0 +1,15 @@
macro invpcid? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & @src.type = 'mem'
if (x86.mode < 64 & @dest.size <> 4) | (x86.mode = 64 & @dest.size <> 8) | @src.size and not 16
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,38h,82h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,149 @@
if ~ defined MMX
restore MMX ; this ensures that symbol cannot be forward-referenced
MMX = 1
element MMX.reg
repeat 8, i:0
element mm#i? : MMX.reg + i
end repeat
iterate context, @dest,@src,@src2,@aux
namespace context
calminstruction MMX.parse_operand#context operand
call x86.parse_operand#context, operand
check type = 'imm' & size = 0
jno done
check imm eq 1 elementof imm & 1 metadataof imm relativeto MMX.reg
jno done
compute type, 'mmreg'
compute mod, 11b
compute rm, 1 metadataof imm - MMX.reg
compute size, 8
done:
end calminstruction
end namespace
end iterate
calminstruction MMX.basic_instruction ext,dest,src
call MMX.parse_operand@dest, dest
call MMX.parse_operand@src, src
check (@src.size or @dest.size) and not 8
jno size_ok
err 'invalid operand size'
size_ok:
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
jno invalid_combination_of_operands
xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm
exit
invalid_combination_of_operands:
err 'invalid combination of operands'
end calminstruction
iterate <instr,opcode>, punpcklbw,60h, punpcklwd,61h, punpckldq,62h, packsswb,63h, pcmpgtb,64h, pcmpgtw,65h, pcmpgtd,66h, packuswb,67h, punpckhbw,68h, \
punpckhwd,69h, punpckhdq,6Ah, packssdw,6Bh, pcmpeqb,74h, pcmpeqw,75h, pcmpeqd,76h, pmullw,0D5h, psubusb,0D8h, psubusw,0D9h, \
pand,0DBh, paddusb,0DCh, paddusw,0DDh, pandn,0DFh, pmulhw,0E5h, psubsb,0E8h, psubsw,0E9h, por,0EBh, paddsb,0ECh, paddsw,0EDh, \
pxor,0EFh, pmaddwd,0F5h, psubb,0F8h, psubw,0F9h, psubd,0FAh, paddb,0FCh, paddw,0FDh, paddd,0FEh
macro instr? dest*,src*
MMX.basic_instruction opcode,dest,src
end macro
end iterate
calminstruction movq? dest*,src*
call MMX.parse_operand@dest, dest
call MMX.parse_operand@src, src
check (@src.size or @dest.size) and not 8
jno size_ok
err 'invalid operand size'
size_ok:
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
jyes mmreg_mem
check @dest.type = 'mem' & @src.type = 'mmreg'
jyes mem_mmreg
err 'invalid combination of operands'
exit
mmreg_mem:
xcall x86.store_instruction@src, <0Fh,6Fh>,@dest.rm
exit
mem_mmreg:
xcall x86.store_instruction@dest, <0Fh,7Fh>,@src.rm
exit
end calminstruction
calminstruction movd? dest*,src*
call MMX.parse_operand@dest, dest
call MMX.parse_operand@src, src
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg')
jyes mmreg_rm
check (@dest.type = 'mem' | @dest.type = 'reg') & @src.type = 'mmreg'
jyes rm_mmreg
err 'invalid combination of operands'
exit
mmreg_rm:
check @src.size and not 4
jno mmreg_rm_ok
err 'invalid operand size'
mmreg_rm_ok:
xcall x86.store_instruction@src, <0Fh,6Eh>,@dest.rm
exit
rm_mmreg:
check @dest.size and not 4
jno rm_mmreg_ok
err 'invalid operand size'
rm_mmreg_ok:
xcall x86.store_instruction@dest, <0Fh,7Eh>,@src.rm
end calminstruction
calminstruction MMX.bit_shift_instruction ext,dest,src
call MMX.parse_operand@dest, dest
call MMX.parse_operand@src, src
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
jyes mmreg_rm
check @dest.type = 'mmreg' & @src.type = 'imm'
jyes mmreg_imm
err 'invalid combination of operands'
exit
mmreg_rm:
check @src.size and not 8
jno mmreg_rm_ok
err 'invalid operand size'
mmreg_rm_ok:
xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm
exit
mmreg_imm:
check @src.size and not 1
jno rm_mmreg_ok
err 'invalid operand size'
rm_mmreg_ok:
local iext, irm
compute iext, 70h+(ext and 0Fh)
compute irm, ((ext shr 4)-0Ch) shl 1
xcall x86.store_instruction@dest, <0Fh,iext>,irm,byte,@src.imm
end calminstruction
iterate <instr,opcode>, psrlw,0D1h, psrld,0D2h, psrlq,0D3h, psrad,0E2h, psraw,0E1h, psllw,0F1h, pslld,0F2h, psllq,0F3h
macro instr? dest*,src*
MMX.bit_shift_instruction opcode,dest,src
end macro
end iterate
macro emms?
db 0Fh,77h
end macro
end if

View File

@ -0,0 +1,23 @@
if ~ defined AVX512
define x86.dqqword? :64
define x86.zword? :64
end if
macro movdir64b? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & @src.type = 'mem'
if @src.size and not 64
err 'invalid operand size'
end if
if (@src.mode = 16 & @dest.size <> 2) | (@src.mode = 32 & @dest.size <> 4) | (@src.mode = 64 & @dest.size <> 8)
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,38h,0F8h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,19 @@
macro movdiri? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @src.type = 'reg' & @dest.type = 'mem'
if @dest.size <> 0 & @src.size <> @dest.size
err 'operand sizes do not match'
end if
if @src.size = 8 & x86.mode = 64
@dest.prefix = 48h
else if @src.size <> 4
err 'invalid operand size'
end if
x86.store_instruction@dest <0Fh,38h,0F9h>,@src.rm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,196 @@
if ~ defined MPX
restore MPX ; this ensures that symbol cannot be forward-referenced
MPX = 1
element MPX.bnd
repeat 4, i:0
element bnd#i? : MPX.bnd + i
end repeat
macro MPX.parse_operand ns,op
x86.parse_operand#ns op
if ns.type = 'imm' & ns.size = 0 & ns.imm eq 1 elementof ns.imm & 1 metadataof ns.imm relativeto MPX.bnd
ns.type = 'bnd'
ns.mod = 11b
ns.rm = 1 metadataof ns.imm - MPX.bnd
ns.size = 0
end if
end macro
macro MPX.parse_sib_operand ns,op&
match [b=,si], op
ns.split = 1
ns.segment_prefix = 0
ns.prefix = 0
ns.opcode_prefix = 0
ns.rex_prefix = 0
ns.size = 0
ns.type = 'mem'
ns.base_part = +b
ns.index_part = +si
if x86.mode = 64
ns.mode = 64
ns.address_registers_type = x86.r64
else
ns.mode = 32
ns.address_registers_type = x86.r32
end if
ns.base_registers = 0
ns.index_registers = 0
repeat elementsof ns.base_part
if % metadataof ns.base_part relativeto x86.r16 | % metadataof ns.base_part relativeto x86.r32 | % metadataof ns.base_part relativeto x86.r64 | % metadataof ns.address relativeto x86.ip
ns.base_registers = ns.base_registers + % elementof ns.base_part * % scaleof ns.base_part
end if
end repeat
repeat elementsof ns.index_part
if % metadataof ns.index_part relativeto x86.r16 | % metadataof ns.index_part relativeto x86.r32 | % metadataof ns.index_part relativeto x86.r64 | % metadataof ns.address relativeto x86.ip
ns.index_registers = ns.index_registers + % elementof ns.index_part * % scaleof ns.index_part
end if
end repeat
ns.displacement = ns.base_part - ns.base_registers + ns.index_part - ns.index_registers
if ns.index_registers eq 0
ns.index = 4
ns.scale = 1
else if elementsof ns.index_registers = 1 & 1 metadataof ns.index_registers relativeto ns.address_registers_type & 1 metadataof ns.index_registers - ns.address_registers_type <> 4
ns.index = 1 metadataof ns.index_registers - ns.address_registers_type
ns.scale = 1 scaleof ns.index_registers
else
err 'invalid address'
end if
if ns.base_registers eq 0
ns.rm = 4
ns.base = 5
ns.index_only = 1
else if ns.base_registers eq 1 elementof ns.base_registers & 1 metadataof ns.base_registers relativeto ns.address_registers_type
ns.base = 1 metadataof ns.base_registers - ns.address_registers_type
if ns.index = 4 & ns.base <> 4
ns.rm = ns.base
else
ns.rm = 4
end if
ns.index_only = 0
else
err 'invalid address'
end if
ns.auto_relative = 0
ns.displacement_size = 4
ns.mod = 2
if ns.index_only
ns.mod = 0
else if ns.displacement relativeto 0
if ns.displacement = 0 & ns.rm and 111b <> 5 & (ns.rm <> 4 | ns.base and 111b <> 5)
ns.displacement_size = 0
ns.mod = 0
else if ns.displacement < 80h & ns.displacement >= -80h
ns.displacement_size = 1
ns.mod = 1
else if ns.displacement - 1 shl ns.mode >= -80h & ns.displacement < 1 shl ns.mode
ns.displacement = ns.displacement - 1 shl ns.mode
ns.displacement_size = 1
ns.mod = 1
end if
end if
else
ns.split = 0
x86.parse_operand#ns op
end match
end macro
macro bndmk? dest*,src*&
MPX.parse_operand @dest,dest
MPX.parse_sib_operand @src,src
if @dest.type = 'bnd' & @src.type = 'mem'
if @src.split & ~ 0 scaleof @src.base_part eq 0
err 'invalid base address'
end if
if (x86.mode = 64 & @src.size and not 8) | (x86.mode < 64 & @src.size and not 4)
err 'invalid operand size'
end if
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,1Bh>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro bndmov? dest*,src*
MPX.parse_operand @dest,dest
MPX.parse_operand @src,src
if @dest.type = 'bnd' & (@src.type = 'bnd' | @src.type = 'mem')
if (x86.mode = 64 & @src.size and not 16) | (x86.mode < 64 & @src.size and not 8)
err 'invalid operand size'
end if
if @src.type = 'mem' & @src.mode <> x86.mode
err 'invalid address'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,1Ah>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'bnd'
if (x86.mode = 64 & @dest.size and not 16) | (x86.mode < 64 & @dest.size and not 8)
err 'invalid operand size'
end if
if @dest.type = 'mem' & @dest.mode <> x86.mode
err 'invalid address'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,1Bh>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,prefix,ext>, bndcl,0F3h,1Ah, bndcu,0F2h,1Ah, bndcn,0F2h,1Bh
macro instr? dest*,src*
MPX.parse_operand @dest,dest
x86.parse_operand @src,src
if @dest.type = 'bnd' & (@src.type = 'reg' | @src.type = 'mem')
if (x86.mode = 64 & @src.size and not 8) | (x86.mode < 64 & @src.size and not 4)
err 'invalid operand size'
end if
if @src.type = 'mem' & @src.mode <> x86.mode
err 'invalid address'
end if
@src.opcode_prefix = prefix
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid operand'
end if
end macro
end iterate
macro bndldx? dest*,src*&
MPX.parse_operand @dest,dest
MPX.parse_sib_operand @src,src
if @dest.type = 'bnd' & @src.type = 'mem'
if @src.scale > 1 | ( @src.split & ~ 0 scaleof @src.index_part eq 0 )
err 'invalid index'
end if
x86.store_instruction@src <0Fh,1Ah>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro bndstx? operands*&
match [dest] =, src, operands
MPX.parse_sib_operand @dest,[dest]
MPX.parse_operand @src,src
if @dest.type = 'mem' & @src.type = 'bnd'
if @dest.scale > 1 | ( @dest.split & ~ 0 scaleof @dest.index_part eq 0 )
err 'invalid index'
end if
x86.store_instruction@dest <0Fh,1Bh>,@src.rm
else
err 'invalid combination of operands'
end if
else
err 'invalid combination of operands'
end match
end macro
end if

View File

@ -0,0 +1,14 @@
include 'sse.inc'
macro pclmulqdq? dest*,src*,imm*
SSE.basic_instruction_imm8 66h,<3Ah,44h>,16,dest,src,imm
end macro
if defined AVX
macro vpclmulqdq? dest*,src*,src2*,imm*
AVX.basic_instruction_imm8 VEX_66_0F3A_W0,44h,16,dest,src,src2,imm
end macro
end if

View File

@ -0,0 +1,18 @@
macro ptwrite? src*
x86.parse_operand@src src
if @src.size = 0
err 'operand size not specified'
else if @src.size <> 4 & (@src.size <> 8 | x86.mode <> 64)
err 'invalid operand size'
end if
if @src.type = 'reg' | @src.type = 'mem'
if @src.size = 8
x86.select_operand_prefix@src 8
end if
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,0AEh>,4
else
err 'invalid operand'
end if
end macro

View File

@ -0,0 +1,10 @@
macro rdrand? dest*
x86.parse_operand@dest dest
if @dest.type = 'reg'
x86.select_operand_prefix@dest @dest.size
x86.store_instruction@dest <0Fh,0C7h>,6
else
err 'invalid operand'
end if
end macro

View File

@ -0,0 +1,10 @@
macro rdseed? dest*
x86.parse_operand@dest dest
if @dest.type = 'reg'
x86.select_operand_prefix@dest @dest.size
x86.store_instruction@dest <0Fh,0C7h>,7
else
err 'invalid operand'
end if
end macro

View File

@ -0,0 +1,4 @@
macro rdtscp?
db 0Fh,1,0F9h
end macro

View File

@ -0,0 +1,39 @@
macro xbegin? dest*
x86.parse_jump_operand@dest dest
if @dest.type = 'imm' & ~ @dest.jump_type
if x86.mode shr 3 <> @dest.size
err 'invalid operand size'
end if
if x86.mode = 16
db 0C7h,0F8h
dw @dest.imm-($+2)
else
if ~ $ relativeto 0 & @dest.imm relativeto 0
@dest.imm = @dest.imm + $ - 0 scaleof $
err 'invalid address'
end if
if @dest.unresolved | ( @dest.imm relativeto $ & @dest.imm-($+5) < 8000h & @dest.imm-($+5) >= -8000h )
db 66h,0C7h,0F8h
dw @dest.imm-($+2)
else
db 0C7h,0F8h
dd @dest.imm-($+4)
end if
end if
else
err 'invalid operand'
end if
end macro
macro xabort? imm*
db 0C6h,0F8h,imm
end macro
macro xend?
db 0Fh,1,0D5h
end macro
macro xtest?
db 0Fh,1,0D6h
end macro

View File

@ -0,0 +1,4 @@
macro getsec?
db 0Fh,37h
end macro

View File

@ -0,0 +1,433 @@
if ~ defined SSE
restore SSE ; this ensures that symbol cannot be forward-referenced
SSE = 1
include 'mmx.inc'
element SSE.reg
repeat 8, i:0
element xmm#i? : SSE.reg + i
end repeat
define x86.dqword? :16
define x86.xword? :16
iterate context, @dest,@src,@src2,@aux
namespace context
calminstruction SSE.parse_operand#context operand
call x86.parse_operand#context, operand
check type = 'imm' & size = 0
jno done
check imm eq 1 elementof imm & 1 metadataof imm relativeto MMX.reg
jyes mm_register
check imm eq 1 elementof imm & 1 metadataof imm relativeto SSE.reg
jyes xmm_register
exit
mm_register:
compute rm, 1 metadataof imm - MMX.reg
compute size, 8
jump export_mmreg
xmm_register:
compute rm, 1 metadataof imm - SSE.reg
compute size, 16
export_mmreg:
compute type, 'mmreg'
compute mod, 11b
done:
end calminstruction
end namespace
end iterate
calminstruction SSE.basic_instruction pre,ext,msize,dest,src
call SSE.parse_operand@dest, dest
call SSE.parse_operand@src, src
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
jno invalid_combination_of_operands
check @dest.size <> 16 | (@src.type = 'mem' & @src.size and not msize) | (@src.type = 'mmreg' & @src.size <> 16)
jno size_ok
err 'invalid operand size'
size_ok:
compute @src.opcode_prefix, pre
xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm
exit
invalid_combination_of_operands:
err 'invalid combination of operands'
end calminstruction
calminstruction SSE.basic_instruction_imm8 pre,ext,msize,dest,src,aux
call SSE.parse_operand@dest, dest
call SSE.parse_operand@src, src
call x86.parse_operand@aux, aux
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'
jno invalid_combination_of_operands
check @dest.size <> 16 | (@src.type = 'mem' & @src.size and not msize) | (@src.type = 'mmreg' & @src.size <> 16) | @aux.size and not 1
jno size_ok
err 'invalid operand size'
size_ok:
compute @src.opcode_prefix, pre
xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm,byte,@aux.imm
exit
invalid_combination_of_operands:
err 'invalid combination of operands'
end calminstruction
iterate <instr,ext>, sqrt,51h, rsqrt,52h, rcp,53h, add,58h, mul,59h, sub,5Ch, min,5Dh, div,5Eh, max,5Fh
macro instr#ps? dest*,src*
SSE.basic_instruction 0,ext,16,dest,src
end macro
macro instr#ss? dest*,src*
SSE.basic_instruction 0F3h,ext,4,dest,src
end macro
end iterate
iterate <instr,ext>, and,54h, andn,55h, or,56h, xor,57h, unpckl,14h, unpckh,15h
macro instr#ps? dest*,src*
SSE.basic_instruction 0,ext,16,dest,src
end macro
end iterate
macro cmpps? dest*,src*,code*
SSE.basic_instruction_imm8 0,0C2h,16,dest,src,code
end macro
macro cmpss? dest*,src*,code*
SSE.basic_instruction_imm8 0F3h,0C2h,4,dest,src,code
end macro
iterate <cond,code>, eq,0, lt,1, le,2, unord,3, neq,4, nlt,5, nle,6, ord,7
macro cmp#cond#ps? dest*,src*
cmpps dest,src,code
end macro
macro cmp#cond#ss? dest*,src*
cmpss dest,src,code
end macro
end iterate
macro shufps? dest*,src*,imm*
SSE.basic_instruction_imm8 0,0C6h,16,dest,src,imm
end macro
iterate <instr,ext>, movaps,28h, movups,10h
macro instr? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
x86.store_instruction@src <0Fh,ext>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
x86.store_instruction@dest <0Fh,ext+1>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, movlps,12h, movhps,16h
macro instr? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mem'
if @dest.size <> 16 | @src.size and not 8
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,ext>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
if @dest.size and not 8 | @src.size <> 16
err 'invalid operand size'
end if
x86.store_instruction@dest <0Fh,ext+1>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, movhlps,12h, movlhps,16h
macro instr? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
if @dest.type = 'mmreg' & @src.type = 'mmreg'
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro movss? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 16 | (@src.type = 'mem' & @src.size and not 4) | (@src.type = 'mmreg' & @src.size <> 16)
err 'invalid operand size'
end if
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,10h>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
if @dest.size and not 4 | @src.size <> 16
err 'invalid operand size'
end if
@dest.opcode_prefix = 0F3h
x86.store_instruction@dest <0Fh,11h>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
macro movntps? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mem' & @src.type = 'mmreg'
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
x86.store_instruction@dest <0Fh,2Bh>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
macro movmskps? dest*,src*
x86.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'reg' & @src.type = 'mmreg'
if (@dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | @src.size <> 16
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,50h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,ext>, ucomiss,2Eh, comiss,2Fh
macro instr? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 16 | (@src.type = 'mem' & @src.size and not 4) | (@src.type = 'mmreg' & @src.size <> 16)
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro cvtpi2ps? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 16 | @src.size and not 8
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,2Ah>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro cvtsi2ss? dest*,src*
SSE.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg')
if @src.size = 0
err 'operand size not specified'
else if @dest.size <> 16 | @src.size < 4
err 'invalid operand size'
end if
x86.select_operand_prefix@src @src.size
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,2Ah>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,ext>, cvttps2pi,2Ch, cvtps2pi,2Dh
macro instr? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 8 | (@src.size = 'mem' & @src.size and not 8) | (@src.size = 'mmreg' & @src.size <> 16)
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, cvttss2si,2Ch, cvtss2si,2Dh
macro instr? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size < 4 | (@src.size = 'mem' & @src.size and not 4) | (@src.size = 'mmreg' & @src.size <> 16)
err 'invalid operand size'
end if
x86.select_operand_prefix@src @dest.size
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, pminub,0DAh, pmaxub,0DEh, pavgb,0E0h, pavgw,0E3h, pmulhuw,0E4h, pminsw,0EAh, pmaxsw,0EEh, psadbw,0F6h
macro instr? dest*,src*
MMX.basic_instruction ext,dest,src
end macro
end iterate
macro pinsrw? dest*,src*,sel*
MMX.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'mmreg' & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm'
if (@src.type = 'reg' & @src.size <> 4) | (@src.type = 'mem' & @src.size and not 2) | @aux.size and not 1
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,0C4h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pextrw? dest*,src*,sel*
x86.parse_operand@dest dest
MMX.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm'
if @dest.size <> 4 | @aux.size and not 1
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,0C5h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pshufw? dest*,src*,sel*
MMX.parse_operand@dest dest
MMX.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'
if @src.size and not 8 | @aux.size and not 1
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,70h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pmovmskb? dest*,src*
x86.parse_operand@dest dest
MMX.parse_operand@src src
if @dest.type = 'reg' & @src.type = 'mmreg'
if @dest.size <> 4
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,0D7h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro movntq? dest*,src*
MMX.parse_operand@dest dest
MMX.parse_operand@src src
if @dest.type = 'mem' & @src.type = 'mmreg'
if @dest.size and not 8
err 'invalid operand size'
end if
x86.store_instruction@dest <0Fh,0E7h>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
macro maskmovq? src*,sel*
MMX.parse_operand@src src
MMX.parse_operand@aux sel
if @src.type = 'mmreg' & @aux.type = 'mmreg'
x86.store_instruction@aux <0Fh,0F7h>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,postbyte>, prefetchnta,0, prefetcht0,1, prefetcht1,2, prefetcht2,3
macro instr? src*
x86.parse_operand@src src
if @src.type = 'mem'
if @src.size and not 1
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,18h>,postbyte
else
err 'invalid operand'
end if
end macro
end iterate
macro sfence?
db 0Fh,0AEh,0F8h
end macro
iterate <instr,postbyte>, fxsave,0, fxrstor,1
macro instr? src*
x86.parse_operand@src src
if @src.type = 'mem'
if @src.size and not 512
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,0AEh>,postbyte
else
err 'invalid operand'
end if
end macro
end iterate
iterate <instr,postbyte>, ldmxcsr,2, stmxcsr,3
macro instr? src*
x86.parse_operand@src src
if @src.type = 'mem'
if @src.size and not 4
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,0AEh>,postbyte
else
err 'invalid operand'
end if
end macro
end iterate
end if

View File

@ -0,0 +1,603 @@
if ~ defined SSE2
restore SSE2 ; this ensures that symbol cannot be forward-referenced
SSE2 = 1
include 'sse.inc'
iterate <instr,ext>, sqrt,51h, rsqrt,52h, rcp,53h, add,58h, mul,59h, sub,5Ch, min,5Dh, div,5Eh, max,5Fh
macro instr#pd? dest*,src*
SSE.basic_instruction 66h,ext,16,dest,src
end macro
macro instr#sd? dest*,src*
SSE.basic_instruction 0F2h,ext,8,dest,src
end macro
end iterate
iterate <instr,ext>, and,54h, andn,55h, or,56h, xor,57h, unpckl,14h, unpckh,15h
macro instr#pd? dest*,src*
SSE.basic_instruction 66h,ext,16,dest,src
end macro
end iterate
macro cmppd? dest*,src*,code*
SSE.basic_instruction_imm8 66h,0C2h,16,dest,src,code
end macro
macro SSE.cmpsd? dest*,src*,code*
SSE.basic_instruction_imm8 0F2h,0C2h,8,dest,src,code
end macro
calminstruction cmpsd? args&
match , args
jno sse
xcall x86.store_operand_prefix, (4)
emit 1, 0A7h
exit
sse:
arrange args, =SSE.=cmpsd args
assemble args
end calminstruction
iterate <cond,code>, eq,0, lt,1, le,2, unord,3, neq,4, nlt,5, nle,6, ord,7
macro cmp#cond#pd? dest*,src*
cmppd dest,src,code
end macro
macro cmp#cond#sd? dest*,src*
cmpsd dest,src,code
end macro
end iterate
macro shufpd? dest*,src*,imm*
SSE.basic_instruction_imm8 66h,0C6h,16,dest,src,imm
end macro
iterate <instr,ext>, movapd,28h, movupd,10h
macro instr? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,ext>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,ext+1>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, movlpd,12h, movhpd,16h
macro instr? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mem'
if @dest.size <> 16 | @src.size and not 8
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,ext>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
if @dest.size and not 8 | @src.size <> 16
err 'invalid operand size'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,ext+1>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro SSE.movsd? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 16 | (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <> 16)
err 'invalid operand size'
end if
@src.opcode_prefix = 0F2h
x86.store_instruction@src <0Fh,10h>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
if @dest.size and not 8 | @src.size <> 16
err 'invalid operand size'
end if
@dest.opcode_prefix = 0F2h
x86.store_instruction@dest <0Fh,11h>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
calminstruction movsd? args&
match , args
jno sse
xcall x86.store_operand_prefix, (4)
emit 1, 0A5h
exit
sse:
arrange args, =SSE.=movsd args
assemble args
end calminstruction
iterate <instr,pre>, movdqa,66h, movdqu,0F3h
macro instr? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
@src.opcode_prefix = pre
x86.store_instruction@src <0Fh,6Fh>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
@dest.opcode_prefix = pre
x86.store_instruction@dest <0Fh,7Fh>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, movntpd,2Bh, movntdq,0E7h
macro instr? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mem' & @src.type = 'mmreg'
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,ext>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro movmskpd? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'reg' & @src.type = 'mmreg'
if (@dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | @src.size <> 16
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,50h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro maskmovdqu? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mmreg'
if (@dest.size or @src.size) <> 16
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,0F7h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,ext>, ucomisd,2Eh, comisd,2Fh
macro instr? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 16 | (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <> 16)
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro cvtps2pd? dest*,src*
SSE.basic_instruction 0,5Ah,8,dest,src
end macro
macro cvtpd2ps? dest*,src*
SSE.basic_instruction 66h,5Ah,16,dest,src
end macro
macro cvtsd2ss? dest*,src*
SSE.basic_instruction 0F2h,5Ah,8,dest,src
end macro
macro cvtss2sd? dest*,src*
SSE.basic_instruction 0F3h,5Ah,4,dest,src
end macro
macro cvtdq2ps? dest*,src*
SSE.basic_instruction 0,5Bh,16,dest,src
end macro
macro cvtps2dq? dest*,src*
SSE.basic_instruction 66h,5Bh,16,dest,src
end macro
macro cvttps2dq? dest*,src*
SSE.basic_instruction 0F3h,5Bh,16,dest,src
end macro
macro cvttpd2dq? dest*,src*
SSE.basic_instruction 66h,0E6h,16,dest,src
end macro
macro cvtpd2dq? dest*,src*
SSE.basic_instruction 0F2h,0E6h,16,dest,src
end macro
macro cvtdq2pd? dest*,src*
SSE.basic_instruction 0F3h,0E6h,8,dest,src
end macro
macro movdq2q? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mmreg'
if @dest.size <> 8 | @src.size <> 16
err 'invalid operand size'
end if
@src.opcode_prefix = 0F2h
x86.store_instruction@src <0Fh,0D6h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro movq2dq? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mmreg'
if @dest.size <> 16 | @src.size <> 8
err 'invalid operand size'
end if
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,0D6h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro cvtpi2pd? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 16 | @src.size and not 8
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,2Ah>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro cvtsi2sd? dest*,src*
SSE.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg')
if @src.size = 0
err 'operand size not specified'
else if @dest.size <> 16 | @src.size < 4
err 'invalid operand size'
end if
x86.select_operand_prefix@src @src.size
@src.opcode_prefix = 0F2h
x86.store_instruction@src <0Fh,2Ah>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,ext>, cvttpd2pi,2Ch, cvtpd2pi,2Dh
macro instr? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 8 | @src.size and not 16
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, cvttsd2si,2Ch, cvtsd2si,2Dh
macro instr? dest*,src*
x86.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size < 4 | (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <>16)
err 'invalid operand size'
end if
x86.select_operand_prefix@src @dest.size
@src.opcode_prefix = 0F2h
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
calminstruction MMX.select_operand_prefix rm_operand*,size*
local sym, prefix
check size = 16
jno no_prefix
compute prefix, 66h
arrange sym, rm_operand.=prefix
publish sym, prefix
exit
no_prefix:
check size <> 8
jno done
err 'invalid operand size'
done:
end calminstruction
calminstruction MMX.basic_instruction ext,dest,src
call SSE.parse_operand@dest, dest
call SSE.parse_operand@src, src
check @src.size and not @dest.size
jno size_ok
err 'operand sizes do not match'
size_ok:
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
jno invalid_combination_of_operands
call MMX.select_operand_prefix, @src,@dest.size
xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm
exit
invalid_combination_of_operands:
err 'invalid combination of operands'
end calminstruction
calminstruction MMX.bit_shift_instruction ext,dest,src
call SSE.parse_operand@dest, dest
call SSE.parse_operand@src, src
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
jyes mmreg_rm
check @dest.type = 'mmreg' & @src.type = 'imm'
jyes mmreg_imm
err 'invalid combination of operands'
exit
mmreg_rm:
check @src.size and not @dest.size
jno mmreg_rm_ok
err 'operand sizes do not match'
mmreg_rm_ok:
call MMX.select_operand_prefix, @src,@dest.size
xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm
exit
mmreg_imm:
check @src.size and not 1
jno rm_mmreg_ok
err 'invalid operand size'
rm_mmreg_ok:
local iext, irm
compute iext, 70h+(ext and 0Fh)
compute irm, ((ext shr 4)-0Ch) shl 1
call MMX.select_operand_prefix, @dest,@dest.size
xcall x86.store_instruction@dest, <0Fh,iext>,irm,byte,@src.imm
end calminstruction
iterate <instr,ext>, paddq,0D4h, pmuludq,0F4h, psubq,0FBh
macro instr? dest*,src*
MMX.basic_instruction ext,dest,src
end macro
end iterate
macro movq? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <> @dest.size)
err 'invalid operand size'
end if
if @dest.size = 8
x86.store_instruction@src <0Fh,6Fh>,@dest.rm
else
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,7Eh>,@dest.rm
end if
else if @dest.type = 'mem' & @src.type = 'mmreg'
if @dest.size and not 8
err 'invalid operand size'
end if
if @src.size = 8
x86.store_instruction@dest <0Fh,7Fh>,@src.rm
else
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,0D6h>,@src.rm
end if
else if @dest.type = 'reg' & @src.type = 'mmreg'
if @dest.size <> 8
err 'invalid operand size'
end if
if @src.size = 16
@dest.opcode_prefix = 66h
end if
@dest.prefix = 48h
x86.store_instruction@dest <0Fh,7Eh>,@src.rm
else if @dest.type = 'mmreg' & @src.type = 'reg'
if @src.size <> 8
err 'invalid operand size'
end if
if @dest.size = 16
@src.opcode_prefix = 66h
end if
@src.prefix = 48h
x86.store_instruction@src <0Fh,6Eh>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro movd? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg')
if @src.size and not 4
err 'invalid operand size'
end if
MMX.select_operand_prefix @src,@dest.size
x86.store_instruction@src <0Fh,6Eh>,@dest.rm
else if (@dest.type = 'mem' | @dest.type = 'reg') & @src.type = 'mmreg'
if @dest.size and not 4
err 'invalid operand size'
end if
MMX.select_operand_prefix @dest,@src.size
x86.store_instruction@dest <0Fh,7Eh>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
macro pinsrw? dest*,src*,sel*
SSE.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'mmreg' & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm'
if (@src.type = 'reg' & @src.size <> 4) | (@src.type = 'mem' & @src.size and not 2) | @aux.size and not 1
err 'invalid operand size'
end if
MMX.select_operand_prefix @src,@dest.size
x86.store_instruction@src <0Fh,0C4h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pextrw? dest*,src*,sel*
x86.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm'
if x86.mode = 64 & @dest.size = 8
@dest.size = 4
end if
if @dest.size <> 4 | @aux.size and not 1
err 'invalid operand size'
end if
MMX.select_operand_prefix @src,@src.size
x86.store_instruction@src <0Fh,0C5h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,pre>, pshufd,66h, pshuflw,0F2h, pshufhw,0F3h
macro instr? dest*,src*,sel*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'
if @dest.size <> 16 | @src.size and not 16 | @aux.size and not 1
err 'invalid operand size'
end if
@src.opcode_prefix = pre
x86.store_instruction@src <0Fh,70h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro pmovmskb? dest*,src*
x86.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'reg' & @src.type = 'mmreg'
if @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)
err 'invalid operand size'
end if
MMX.select_operand_prefix @src,@src.size
x86.store_instruction@src <0Fh,0D7h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,postbyte>, psrldq,3, pslldq,7
macro instr? dest*,cnt*
SSE.parse_operand@dest dest
x86.parse_operand@aux cnt
if @dest.type = 'mmreg' & @aux.type = 'imm'
if @dest.size <> 16 | @aux.size and not 1
err 'invalid operand size'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,73h>,postbyte,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, punpcklqdq,6Ch, punpckhqdq,6Dh
macro instr? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro movnti? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'mem' & @src.type = 'reg'
if @dest.size and not @src.size
err 'operand sizes do not match'
else if @src.size <> 4 & @src.size <> 8
err 'invalid operand size'
end if
x86.select_operand_prefix@dest @src.size
x86.store_instruction@dest <0Fh,0C3h>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
macro clflush? src*
x86.parse_operand@src src
if @src.type = 'mem'
if @src.size and not 1
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,0AEh>,7
else
err 'invalid operand'
end if
end macro
macro lfence?
db 0Fh,0AEh,0E8h
end macro
macro mfence?
db 0Fh,0AEh,0F0h
end macro
end if

View File

@ -0,0 +1,72 @@
include 'sse2.inc'
macro fisttp? src*
x86.parse_operand@src src
if @src.type = 'mem'
if @src.size = 2
x86.store_instruction@src 0DFh,1
else if @src.size = 4
x86.store_instruction@src 0DBh,1
else if @src.size = 8
x86.store_instruction@src 0DDh,1
else if @src.size
err 'invalid operand size'
else
err 'operand size not specified'
end if
else
err 'invalid operand'
end if
end macro
iterate <instr,ext>, addsub,0D0h, hadd,7Ch, hsub,7Dh
macro instr#pd? dest*,src*
SSE.basic_instruction 66h,ext,16,dest,src
end macro
macro instr#ps? dest*,src*
SSE.basic_instruction 0F2h,ext,16,dest,src
end macro
end iterate
iterate <instr,ext>, movsldup,12h, movshdup,16h
macro instr? dest*,src*
SSE.basic_instruction 0F3h,ext,16,dest,src
end macro
end iterate
macro movddup? dest*,src*
SSE.basic_instruction 0F2h,12h,8,dest,src
end macro
macro lddqu? dest*,src*
SSE.parse_operand@src dest
SSE.parse_operand@src src
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
if @dest.type = 'mmreg' & @src.type = 'mem'
@src.opcode_prefix = 0F2h
x86.store_instruction@src <0Fh,0F0h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro monitor? arg1,arg2,arg3
match any, arg1 arg2 arg3
if ~ arg1 eq eax | ~ arg2 eq ecx | ~ arg3 eq edx
err 'invalid combination of operands'
end if
end match
db 0Fh,01h,0C8h
end macro
macro mwait? arg1,arg2
match any, arg1 arg2
if ~ arg1 eq eax | ~ arg2 eq ecx
err 'invalid combination of operands'
end if
end match
db 0Fh,01h,0C9h
end macro

View File

@ -0,0 +1,204 @@
include 'ssse3.inc'
iterate <instr,supp>, ptest,17h, pmuldq,28h, pcmpeqq,29h, packusdw,2Bh, pminsb,38h, pminsd,39h, pminuw,3Ah, pminud,3Bh, pmaxsb,3Ch, pmaxsd,3Dh, pmaxuw,3Eh, pmaxud,3Fh, pmulld,40h, phminposuw,41h
macro instr? dest*,src*
SSE.basic_instruction 66h,<38h,supp>,16,dest,src
end macro
end iterate
iterate <instr,supp>, roundps,08h, roundpd,09h, roundss,0Ah, roundsd,0Bh, blendps,0Ch, blendpd,0Dh, pblendw,0Eh, dpps,40h, dppd,41h, mpsadbw,42h
macro instr? dest*,src*,imm*
SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm
end macro
end iterate
iterate <instr,supp>, pblendvb,10h, blendvps,14h, blendvpd,15h
macro instr? dest*,src*,sel*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
SSE.parse_operand@aux sel
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'mmreg' & @aux.size = 16 & @aux.rm = 0
if @dest.size or @src.size and not 16
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,38h,supp>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <conv,code,msize>, bw,0,8, bd,1,4, bq,2,2, wd,3,8, wq,4,4, dq,5,8
macro pmovsx#conv? dest*,src*
SSE.basic_instruction 66h,<38h,20h+code>,msize,dest,src
end macro
macro pmovzx#conv? dest*,src*
SSE.basic_instruction 66h,<38h,30h+code>,msize,dest,src
end macro
end iterate
macro insertps? dest*,src*,sel*
SSE.basic_instruction_imm8 66h,<3Ah,21h>,4,dest,src,sel
end macro
macro extractps? dest*,src*,sel*
x86.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm'
if x86.mode = 64 & @dest.size = 8
@dest.size = 4
end if
if @dest.size <> 4 | @src.size and not 16 | @aux.size and not 1
err 'invalid operand size'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,3Ah,17h>,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pinsrb? dest*,src*,sel*
SSE.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@aux sel
if (@dest.type = 'mmreg' & @dest.size = 16) & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm'
if (@src.type = 'reg' & @src.size <> 4) | (@src.type = 'mem' & @src.size and not 1) | @aux.size and not 1
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,3Ah,20h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pinsrd? dest*,src*,sel*
SSE.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@aux sel
if (@dest.type = 'mmreg' & @dest.size = 16) & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm'
if @src.size and not 4 | @aux.size and not 1
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,3Ah,22h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pinsrq? dest*,src*,sel*
SSE.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@aux sel
if (@dest.type = 'mmreg' & @dest.size = 16) & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm'
if @src.size and not 8 | @aux.size and not 1
err 'invalid operand size'
end if
if x86.mode < 64
err 'instruction requires long mode'
end if
@src.opcode_prefix = 66h
@src.rex_prefix = 48h
x86.store_instruction@src <0Fh,3Ah,22h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pextrb? dest*,src*,sel*
x86.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux sel
if (@dest.type = 'reg' | @dest.type = 'mem') & (@src.type = 'mmreg' & @src.size = 16) & @aux.type = 'imm'
if x86.mode = 64 & @dest.type = 'reg' & @dest.size = 8
@dest.size = 4
end if
if (@dest.type = 'reg' & @dest.size <> 4) | (@dest.size = 'mem' & @dest.size and not 1) | @aux.size and not 1
err 'invalid operand size'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,3Ah,14h>,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pextrw? dest*,src*,sel*
x86.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm'
if x86.mode = 64 & @dest.size = 8
@dest.size = 4
end if
if @dest.size <> 4 | @aux.size and not 1
err 'invalid operand size'
end if
MMX.select_operand_prefix @src,@src.size
x86.store_instruction@src <0Fh,0C5h>,@dest.rm,1,@aux.imm
else if @dest.type = 'mem' & (@src.type = 'mmreg' & @src.size = 16) & @aux.type = 'imm'
if @dest.size and not 2 | @aux.size and not 1
err 'invalid operand size'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,3Ah,15h>,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pextrd? dest*,src*,sel*
x86.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux sel
if (@dest.type = 'reg' | @dest.type = 'mem') & (@src.type = 'mmreg' & @src.size = 16) & @aux.type = 'imm'
if x86.mode = 64 & @dest.type = 'reg' & @dest.size = 8
@dest.size = 4
end if
if @dest.size and not 4 | @aux.size and not 1
err 'invalid operand size'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,3Ah,16h>,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pextrq? dest*,src*,sel*
x86.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux sel
if (@dest.type = 'reg' | @dest.type = 'mem') & (@src.type = 'mmreg' & @src.size = 16) & @aux.type = 'imm'
if @dest.size and not 8 | @aux.size and not 1
err 'invalid operand size'
end if
if x86.mode < 64
err 'instruction requires long mode'
end if
@dest.opcode_prefix = 66h
@dest.rex_prefix = 48h
x86.store_instruction@dest <0Fh,3Ah,16h>,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro movntdqa? dest*,src*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mem'
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,38h,2Ah>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,54 @@
include 'sse4.1.inc'
iterate <instr,supp>, pcmpgtq,37h
macro instr? dest*,src*
SSE.basic_instruction 66h,<38h,supp>,16,dest,src
end macro
end iterate
iterate <instr,supp>, pcmpestrm,60h, pcmpestri,61h, pcmpistrm,62h, pcmpistri,63h
macro instr? dest*,src*,imm*
SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm
end macro
end iterate
macro crc32? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & ( @src.type = 'reg' | @src.type = 'mem' )
if @dest.size <> 4 & ( @dest.size <> 8 | x86.mode <> 64 )
err 'invalid operand size'
end if
@src.opcode_prefix = 0F2h
if @src.size > 1
x86.select_operand_prefix@src @src.size
x86.store_instruction@src <0Fh,38h,0F1h>,@dest.rm
else if @src.size > 0
x86.store_instruction@src <0Fh,38h,0F0h>,@dest.rm
else
err 'operand size not specified'
end if
else
err 'invalid combination of operands'
end if
end macro
macro popcnt? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & ( @src.type = 'reg' | @src.type = 'mem' )
if @src.size and not @dest.size
err 'operand sizes do not match'
end if
@src.opcode_prefix = 0F3h
if @dest.size > 1
x86.select_operand_prefix@src @dest.size
x86.store_instruction@src <0Fh,0B8h>,@dest.rm
else
err 'invalid operand size'
end if
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,26 @@
include 'sse3.inc'
iterate <instr,supp>, pshufb,0, phaddw,1, phaddd,2, phaddsw,3, pmaddubsw,4, phsubw,5, phsubd,6, phsubsw,7, psignb,8, psignw,9, psignd,0Ah, pmulhrsw,0Bh, pabsb,1Ch, pabsw,1Dh, pabsd,1Eh
macro instr? dest*,src*
MMX.basic_instruction <38h,supp>,dest,src
end macro
end iterate
macro palignr? dest*,src*,aux*
SSE.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'
if @src.size and not @dest.size
err 'operand sizes do not match'
end if
if @aux.size and not 1
err 'invalid operand size'
end if
MMX.select_operand_prefix @src,@dest.size
x86.store_instruction@src <0Fh,3Ah,0Fh>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,37 @@
include 'aes.inc'
if defined AVX_512
iterate <instr,opcode>, aesenc,0DCh, aesenclast,0DDh, aesdec,0DEh, aesdeclast,0DFh
macro v#instr? dest*,src*,src2*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg')
if @dest.size <> @src.size | @src2.size and not @dest.size
err 'operand sizes do not match'
end if
@src2.memsize = 0
AVX_512.store_instruction@src2 @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
else
include 'avx.inc'
iterate <instr,opcode>, aesenc,0DCh, aesenclast,0DDh, aesdec,0DEh, aesdeclast,0DFh
macro v#instr? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W0,opcode,0,dest,src,src2
end macro
end iterate
end if

View File

@ -0,0 +1,65 @@
iterate <instr,prefix,ext,postbyte>, vmxon,0F3h,0C7h,6, vmclear,66h,0C7h,6, \
vmptrld,0,0C7h,6, vmptrst,0,0C7h,7
macro instr? src*
x86.parse_operand@src src
if @src.type = 'mem'
if @src.size and not 8
err 'invalid operand size'
else
@src.opcode_prefix = prefix
x86.store_instruction@src <0Fh,ext>,postbyte
end if
else
err 'invalid operand'
end if
end macro
end iterate
macro vmxoff?
db 0Fh,1,0C4h
end macro
macro vmcall?
db 0Fh,1,0C1h
end macro
macro vmlaunch?
db 0Fh,1,0C2h
end macro
macro vmresume?
db 0Fh,1,0C3h
end macro
macro vmread? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @src.type = 'reg' & (@dest.type = 'mem' | @dest.type = 'reg')
if (x86.mode < 64 & @src.size <> 4) | (x86.mode = 64 & @src.size <> 8)
err 'invalid operand size'
else if @dest.size and not @src.size
err 'operand sizes do not match'
end if
x86.store_instruction@dest <0Fh,78h>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
macro vmwrite? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg')
if (x86.mode < 64 & @dest.size <> 4) | (x86.mode = 64 & @dest.size <> 8)
err 'invalid operand size'
else if @src.size and not @dest.size
err 'operand sizes do not match'
end if
x86.store_instruction@src <0Fh,79h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,32 @@
include 'pclmulqdq.inc'
if defined AVX_512
macro vpclmulqdq? dest*,src*,src2*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm'
if @aux.size and not 1
err 'invalid operand size'
else if @dest.size <> @src.size | @src2.size and not @dest.size
err 'operand sizes do not match'
end if
@src2.memsize = 0
AVX_512.store_instruction@src2 @dest.size,VEX_66_0F3A_W0,EVEX_AS_VEX+EVEX_VL,44h,@dest.mask,@dest.rm,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
else
include 'avx.inc'
macro vpclmulqdq? dest*,src*,src2*,imm*
AVX.basic_instruction_imm8 VEX_66_0F3A_W0,44h,0,dest,src,src2,imm
end macro
end if

View File

@ -0,0 +1,35 @@
iterate <instr,postbyte>, xsave,4, xrstor,5
macro instr? src*
x86.parse_operand@src src
if @src.type = 'mem'
x86.store_instruction@src <0Fh,0AEh>,postbyte
else
err 'invalid operand'
end if
end macro
macro instr#64? src*
if x86.mode = 64
x86.parse_operand@src src
if @src.type = 'mem'
x86.select_operand_prefix@src 8
x86.store_instruction@src <0Fh,0AEh>,postbyte
else
err 'invalid operand'
end if
else
err 'instruction requires long mode'
end if
end macro
end iterate
macro xgetbv?
db 0Fh,1,0D0h
end macro
macro xsetbv?
db 0Fh,1,0D1h
end macro

View File

@ -0,0 +1,470 @@
macro struct? name
macro end?.struct?!
end namespace
esc end struc
virtual at 0
name name
sizeof.name = $
end virtual
purge end?.struct?
end macro
esc struc name
label . : sizeof.name
namespace .
end macro
struct SCNHDR
s_name db 8 dup ?
s_paddr dd ?
s_vaddr dd ?
s_size dd ?
s_scnptr dd ?
s_relptr dd ?
s_lnnoptr dd ?
s_nreloc dw ?
s_nlnno dw ?
s_flags dd ?
end struct
SCNHSZ = sizeof SCNHDR
struct RELOC
r_vaddr dd ?
r_symndx dd ?
r_type dw ?
end struct
RELSZ = sizeof RELOC
struct SYMENT
e_name db 8 dup ?
virtual at e_name
e_zeroes dd ?
e_offset dd ?
end virtual
e_value dd ?
e_scnum dw ?
e_type dw ?
e_sclass db ?
e_numaux db ?
end struct
SYMESZ = sizeof SYMENT
I386MAGIC = 0x14c
F_RELFLG = 0x0001
F_EXEC = 0x0002
F_LNNO = 0x0004
F_LSYMS = 0x0008
F_AR32WR = 0x0100
STYP_TEXT = 0x0020
STYP_DATA = 0x0040
STYP_BSS = 0x0080
N_UNDEF = 0
N_ABS = -1
N_DEBUG = -2
T_NULL = 0000b
T_VOID = 0001b
T_CHAR = 0010b
T_SHORT = 0011b
T_INT = 0100b
T_LONG = 0101b
T_FLOAT = 0110b
T_DOUBLE = 0111b
T_STRUCT = 1000b
T_UNION = 1001b
T_ENUM = 1010b
T_MOE = 1011b
T_UCHAR = 1100b
T_USHORT = 1101b
T_UINT = 1110b
T_ULONG = 1111b
T_LNGDBL = 01_0000b
DT_NON = 00b
DT_PTR = 01b
DT_FCN = 10b
DT_ARY = 11b
C_NULL = 0
C_AUTO = 1
C_EXT = 2
C_STAT = 3
C_REG = 4
C_EXTDEF = 5
C_LABEL = 6
C_ULABEL = 7
C_MOS = 8
C_ARG = 9
C_STRTAG = 10
C_MOU = 11
C_UNTAG = 12
C_TPDEF = 13
C_USTATIC = 14
C_ENTAG = 15
C_MOE = 16
C_REGPARM = 17
C_FIELD = 18
C_AUTOARG = 19
C_LASTENT = 20
C_BLOCK = 100
C_FCN = 101
C_EOS = 102
C_FILE = 103
C_LINE = 104
C_ALIAS = 105
C_HIDDEN = 106
C_EFCN = 255
RELOC_ADDR32 = 6
RELOC_REL32 = 20
COFF::
namespace COFF
Header:
f_magic dw I386MAGIC
f_nscns dw NUMBER_OF_SECTIONS
f_timdat dd __TIME__
f_symptr dd SYMBOL_TABLE_OFFSET
f_nsyms dd NUMBER_OF_SYMBOLS
f_opthdr dw 0
f_flags dw F_AR32WR + F_LNNO
Sections: db NUMBER_OF_SECTIONS * SCNHSZ dup 0
virtual at 0
symbol_table:: rb NUMBER_OF_SYMBOLS * SYMESZ
end virtual
virtual at 0
string_table:: dd STRING_TABLE_SIZE
STRING_POSITION = $
rb STRING_TABLE_SIZE - $
end virtual
virtual at 0
relocations:: rb NUMBER_OF_RELOCATIONS * RELSZ
end virtual
element relocatable?
macro section_start
local sym
element sym : relocatable * (1+SECTION_INDEX) + SYMBOL_INDEX
SECTION_BASE = sym
org sym
if DEFINED_SECTION | defined DEFAULT_SECTION
store SECTION_NAME : 8 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_name
store C_STAT at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_sclass
store 1+SECTION_INDEX at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_scnum
SYMBOL_INDEX = SYMBOL_INDEX + 1
end if
end macro
RELOCATION_INDEX = 0
SECTION_INDEX = 0
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
SYMBOL_INDEX = 0
SECTION_OFFSET = $%
SECTION_ALIGN = 4
SECTION_NAME = '.flat'
SECTION_FLAGS = STYP_TEXT + STYP_DATA
DEFINED_SECTION = 0
section_start
end namespace
macro section?
namespace COFF
SECTION_SIZE = $% - SECTION_OFFSET
if DEFINED_SECTION | SECTION_SIZE > 0
if ~ DEFINED_SECTION
DEFAULT_SECTION := 1
end if
if $%% = SECTION_OFFSET
SECTION_FLAGS = SECTION_FLAGS or STYP_BSS
SECTION_OFFSET = 0
section $
else
UNINITIALIZED_LENGTH = $% - $%%
section $
db UNINITIALIZED_LENGTH dup 0
end if
store SECTION_NAME : 8 at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_name
store SECTION_OFFSET at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_scnptr
store SECTION_SIZE at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_size
store SECTION_FLAGS at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_flags
if RELOCATION_INDEX > SECTION_RELOCATION_INDEX
store RELOCATION_INDEX - SECTION_RELOCATION_INDEX at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_nreloc
store RELOCATIONS_OFFSET + SECTION_RELOCATION_INDEX * RELSZ at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_relptr
end if
SECTION_INDEX = SECTION_INDEX + 1
end if
end namespace
end macro
macro section? declaration*
namespace COFF
section
DEFINED_SECTION = 1
SECTION_FLAGS = 0
SECTION_OFFSET = $%
SECTION_ALIGN = 4
match name attributes, declaration
SECTION_NAME = name
local seq,list
define seq attributes
while 1
match car cdr, seq
define list car
define seq cdr
else
match any, seq
define list any
end match
break
end match
end while
irpv attribute, list
match =code?, attribute
SECTION_FLAGS = SECTION_FLAGS or STYP_TEXT
else match =data?, attribute
SECTION_FLAGS = SECTION_FLAGS or STYP_DATA
else
err 'unknown attribute "',`attribute,'"'
end match
end irpv
else
SECTION_NAME = declaration
end match
section_start
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
end namespace
end macro
calminstruction align? boundary,value:?
check COFF.SECTION_ALIGN mod (boundary) = 0
jyes allowed
err 'section not aligned enough'
exit
allowed:
compute boundary, (boundary-1)-($-COFF.SECTION_BASE+boundary-1) mod boundary
arrange value, =db boundary =dup value
assemble value
end calminstruction
macro public? declaration*
namespace COFF
match =static? value =as? str, declaration
SYMBOL_VALUE = value
SYMBOL_NAME = string str
SYMBOL_CLASS = C_STAT
else match value =as? str, declaration
SYMBOL_VALUE = value
SYMBOL_NAME = string str
SYMBOL_CLASS = C_EXT
else match =static? value, declaration
SYMBOL_VALUE = value
SYMBOL_NAME = `value
SYMBOL_CLASS = C_STAT
else
SYMBOL_VALUE = declaration
SYMBOL_NAME = `declaration
SYMBOL_CLASS = C_EXT
end match
if SYMBOL_VALUE relativeto 1 elementof SYMBOL_VALUE & 1 elementof (1 metadataof SYMBOL_VALUE) relativeto relocatable & 1 scaleof (1 metadataof SYMBOL_VALUE) > 0
SYMBOL_SECTION_INDEX = 1 scaleof (1 metadataof SYMBOL_VALUE)
SYMBOL_VALUE = SYMBOL_VALUE - 1 elementof SYMBOL_VALUE
else
SYMBOL_SECTION_INDEX = N_ABS
end if
if lengthof SYMBOL_NAME > 8
store 0 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_zeroes
store STRING_POSITION at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_offset
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
else
store SYMBOL_NAME : 8 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_name
end if
store SYMBOL_VALUE at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_value
store SYMBOL_SECTION_INDEX at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_scnum
store SYMBOL_CLASS at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_sclass
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
macro extrn? declaration*
namespace COFF
local sym,psym
element sym : relocatable * (-1) + SYMBOL_INDEX
match str =as? name:size, declaration
label name:size at sym
SYMBOL_NAME = string str
else match name:size, declaration
label name:size at sym
SYMBOL_NAME = `name
else match str =as? name, declaration
label name at sym
SYMBOL_NAME = string str
else
label declaration at sym
SYMBOL_NAME = `declaration
end match
if lengthof SYMBOL_NAME > 8
store 0 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_zeroes
store STRING_POSITION at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_offset
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
else
store SYMBOL_NAME : 8 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_name
end if
store C_EXT at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_sclass
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
calminstruction calminstruction?.initsym? var*, val&
publish var, val
end calminstruction
calminstruction calminstruction?.asm? line&
local name, i
initsym name, name.0
match name.i, name
compute i, i+1
arrange name, name.i
publish name, line
arrange line, =assemble name
assemble line
end calminstruction
calminstruction dword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable
jyes addr32
check ~ value relativeto 0 & (value + COFF.SECTION_BASE) relativeto 1 elementof (value + COFF.SECTION_BASE)
jno plain
check 1 elementof (1 metadataof (value + COFF.SECTION_BASE)) relativeto COFF.relocatable
jyes rel32
plain:
emit 4, value
exit
local offset, symndx, type
addr32:
compute symndx, 0 scaleof (1 metadataof value)
compute type, RELOC_ADDR32
jump add_relocation
rel32:
compute value, value + COFF.SECTION_BASE
compute symndx, 0 scaleof (1 metadataof value)
compute type, RELOC_REL32
jump add_relocation
add_relocation:
compute offset, $%
emit 4, 0 scaleof value
check $% > offset
jno done
compute offset, offset - COFF.SECTION_OFFSET
local reloc
compute reloc, COFF.RELOCATION_INDEX * RELSZ
asm store offset at COFF.relocations : reloc + RELOC.r_vaddr
asm store symndx at COFF.relocations : reloc + RELOC.r_symndx
asm store type at COFF.relocations : reloc + RELOC.r_type
compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1
done:
end calminstruction
calminstruction dd? definitions&
local value, n
start:
match value=,definitions, definitions, ()
jyes recognize
match value, definitions
arrange definitions,
recognize:
match n =dup? value, value, ()
jyes duplicate
match ?, value
jyes reserve
call dword, value
next:
match , definitions
jno start
take , definitions
take definitions, definitions
jyes next
exit
reserve:
emit dword
jump next
duplicate:
match (value), value
stack:
check n
jno next
take definitions, value
arrange value, definitions
compute n, n - 1
jump stack
end calminstruction
calminstruction (label) dd? definitions&
local cmd
arrange cmd, =label label : =dword
assemble cmd
arrange cmd, =dd definitions
assemble cmd
end calminstruction
postpone
purge section?
section
namespace COFF
NUMBER_OF_SECTIONS := SECTION_INDEX
STRING_TABLE_SIZE := STRING_POSITION
NUMBER_OF_SYMBOLS := SYMBOL_INDEX
NUMBER_OF_RELOCATIONS := RELOCATION_INDEX
RELOCATIONS_OFFSET = $%
load byte_sequence : NUMBER_OF_RELOCATIONS * RELSZ from relocations:0
db byte_sequence
SYMBOL_TABLE_OFFSET = $%
load byte_sequence : NUMBER_OF_SYMBOLS * SYMESZ from symbol_table:0
db byte_sequence
load byte_sequence : STRING_TABLE_SIZE from string_table:0
db byte_sequence
end namespace
end postpone

View File

@ -0,0 +1,754 @@
macro struct? name
macro end?.struct?!
end namespace
esc end struc
virtual at 0
name name
sizeof.name = $
end virtual
purge end?.struct?
end macro
esc struc name
label . : sizeof.name
namespace .
end macro
struct IMAGE_SECTION_HEADER
Name db 8 dup ?
VirtualSize dd ?
VirtualAddress dd ?
SizeOfRawData dd ?
PointerToRawData dd ?
PointerToRelocations dd ?
PointerToLinenumbers dd ?
NumberOfRelocations dw ?
NumberOfLinenumbers dw ?
Characteristics dd ?
end struct
struct IMAGE_RELOCATION
VirtualAddress dd ?
SymbolTableIndex dd ?
Type dw ?
end struct
struct IMAGE_SYMBOL
ShortName db 8 dup ?
virtual at ShortName
Zeroes dd ?
Offset dd ?
end virtual
Value dd ?
SectionNumber dw ?
Type dw ?
StorageClass db ?
NumberOfAuxSymbols db ?
end struct
IMAGE_FILE_MACHINE_UNKNOWN = 0x0
IMAGE_FILE_MACHINE_AM33 = 0x1D3
IMAGE_FILE_MACHINE_AMD64 = 0x8664
IMAGE_FILE_MACHINE_ARM = 0x1C0
IMAGE_FILE_MACHINE_ARMNT = 0x1C4
IMAGE_FILE_MACHINE_ARM64 = 0xAA64
IMAGE_FILE_MACHINE_EBC = 0xEBC
IMAGE_FILE_MACHINE_I386 = 0x14C
IMAGE_FILE_MACHINE_IA64 = 0x200
IMAGE_FILE_MACHINE_M32R = 0x9041
IMAGE_FILE_MACHINE_MIPS16 = 0x266
IMAGE_FILE_MACHINE_MIPSFPU = 0x366
IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466
IMAGE_FILE_MACHINE_POWERPC = 0x1F0
IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1
IMAGE_FILE_MACHINE_R4000 = 0x166
IMAGE_FILE_MACHINE_SH3 = 0x1A2
IMAGE_FILE_MACHINE_SH3DSP = 0x1A3
IMAGE_FILE_MACHINE_SH4 = 0x1A6
IMAGE_FILE_MACHINE_SH5 = 0x1A8
IMAGE_FILE_MACHINE_THUMB = 0x1C2
IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
IMAGE_FILE_RELOCS_STRIPPED = 0x0001
IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002
IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004
IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008
IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010
IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020
IMAGE_FILE_BYTES_REVERSED_LO = 0x0080
IMAGE_FILE_32BIT_MACHINE = 0x0100
IMAGE_FILE_DEBUG_STRIPPED = 0x0200
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400
IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800
IMAGE_FILE_SYSTEM = 0x1000
IMAGE_FILE_DLL = 0x2000
IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000
IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
IMAGE_SCN_TYPE_NO_PAD = 0x00000008
IMAGE_SCN_CNT_CODE = 0x00000020
IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040
IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080
IMAGE_SCN_LNK_OTHER = 0x00000100
IMAGE_SCN_LNK_INFO = 0x00000200
IMAGE_SCN_LNK_REMOVE = 0x00000800
IMAGE_SCN_LNK_COMDAT = 0x00001000
IMAGE_SCN_GPREL = 0x00008000
IMAGE_SCN_MEM_PURGEABLE = 0x00020000
IMAGE_SCN_MEM_16BIT = 0x00020000
IMAGE_SCN_MEM_LOCKED = 0x00040000
IMAGE_SCN_MEM_PRELOAD = 0x00080000
IMAGE_SCN_ALIGN_1BYTES = 0x00100000
IMAGE_SCN_ALIGN_2BYTES = 0x00200000
IMAGE_SCN_ALIGN_4BYTES = 0x00300000
IMAGE_SCN_ALIGN_8BYTES = 0x00400000
IMAGE_SCN_ALIGN_16BYTES = 0x00500000
IMAGE_SCN_ALIGN_32BYTES = 0x00600000
IMAGE_SCN_ALIGN_64BYTES = 0x00700000
IMAGE_SCN_ALIGN_128BYTES = 0x00800000
IMAGE_SCN_ALIGN_256BYTES = 0x00900000
IMAGE_SCN_ALIGN_512BYTES = 0x00A00000
IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000
IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000
IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000
IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000
IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000
IMAGE_SCN_MEM_DISCARDABLE = 0x02000000
IMAGE_SCN_MEM_NOT_CACHED = 0x04000000
IMAGE_SCN_MEM_NOT_PAGED = 0x08000000
IMAGE_SCN_MEM_SHARED = 0x10000000
IMAGE_SCN_MEM_EXECUTE = 0x20000000
IMAGE_SCN_MEM_READ = 0x40000000
IMAGE_SCN_MEM_WRITE = 0x80000000
IMAGE_REL_AMD64_ABSOLUTE = 0x0000
IMAGE_REL_AMD64_ADDR64 = 0x0001
IMAGE_REL_AMD64_ADDR32 = 0x0002
IMAGE_REL_AMD64_ADDR32NB = 0x0003
IMAGE_REL_AMD64_REL32 = 0x0004
IMAGE_REL_AMD64_REL32_1 = 0x0005
IMAGE_REL_AMD64_REL32_2 = 0x0006
IMAGE_REL_AMD64_REL32_3 = 0x0007
IMAGE_REL_AMD64_REL32_4 = 0x0008
IMAGE_REL_AMD64_REL32_5 = 0x0009
IMAGE_REL_AMD64_SECTION = 0x000A
IMAGE_REL_AMD64_SECREL = 0x000B
IMAGE_REL_AMD64_SECREL7 = 0x000C
IMAGE_REL_AMD64_TOKEN = 0x000D
IMAGE_REL_AMD64_SREL32 = 0x000E
IMAGE_REL_AMD64_PAIR = 0x000F
IMAGE_REL_AMD64_SSPAN32 = 0x0010
IMAGE_REL_I386_ABSOLUTE = 0x0000
IMAGE_REL_I386_DIR16 = 0x0001
IMAGE_REL_I386_REL16 = 0x0002
IMAGE_REL_I386_DIR32 = 0x0006
IMAGE_REL_I386_DIR32NB = 0x0007
IMAGE_REL_I386_SEG12 = 0x0009
IMAGE_REL_I386_SECTION = 0x000A
IMAGE_REL_I386_SECREL = 0x000B
IMAGE_REL_I386_TOKEN = 0x000C
IMAGE_REL_I386_SECREL7 = 0x000D
IMAGE_REL_I386_REL32 = 0x0014
IMAGE_SYM_UNDEFINED = 0
IMAGE_SYM_ABSOLUTE = -1
IMAGE_SYM_DEBUG = -2
IMAGE_SYM_TYPE_NULL = 0
IMAGE_SYM_TYPE_VOID = 1
IMAGE_SYM_TYPE_CHAR = 2
IMAGE_SYM_TYPE_SHORT = 3
IMAGE_SYM_TYPE_INT = 4
IMAGE_SYM_TYPE_LONG = 5
IMAGE_SYM_TYPE_FLOAT = 6
IMAGE_SYM_TYPE_DOUBLE = 7
IMAGE_SYM_TYPE_STRUCT = 8
IMAGE_SYM_TYPE_UNION = 9
IMAGE_SYM_TYPE_ENUM = 10
IMAGE_SYM_TYPE_MOE = 11
IMAGE_SYM_TYPE_BYTE = 12
IMAGE_SYM_TYPE_WORD = 13
IMAGE_SYM_TYPE_UINT = 14
IMAGE_SYM_TYPE_DWORD = 15
IMAGE_SYM_DTYPE_NULL = 0
IMAGE_SYM_DTYPE_POINTER = 1
IMAGE_SYM_DTYPE_FUNCTION = 2
IMAGE_SYM_DTYPE_ARRAY = 3
IMAGE_SYM_CLASS_END_OF_FUNCTION = -1
IMAGE_SYM_CLASS_NULL = 0
IMAGE_SYM_CLASS_AUTOMATIC = 1
IMAGE_SYM_CLASS_EXTERNAL = 2
IMAGE_SYM_CLASS_STATIC = 3
IMAGE_SYM_CLASS_REGISTER = 4
IMAGE_SYM_CLASS_EXTERNAL_DEF = 5
IMAGE_SYM_CLASS_LABEL = 6
IMAGE_SYM_CLASS_UNDEFINED_LABEL = 7
IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8
IMAGE_SYM_CLASS_ARGUMENT = 9
IMAGE_SYM_CLASS_STRUCT_TAG = 10
IMAGE_SYM_CLASS_MEMBER_OF_UNION = 11
IMAGE_SYM_CLASS_UNION_TAG = 12
IMAGE_SYM_CLASS_TYPE_DEFINITION = 13
IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14
IMAGE_SYM_CLASS_ENUM_TAG = 15
IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16
IMAGE_SYM_CLASS_REGISTER_PARAM = 17
IMAGE_SYM_CLASS_BIT_FIELD = 18
IMAGE_SYM_CLASS_BLOCK = 100
IMAGE_SYM_CLASS_FUNCTION = 101
IMAGE_SYM_CLASS_END_OF_STRUCT = 102
IMAGE_SYM_CLASS_FILE = 103
IMAGE_SYM_CLASS_SECTION = 104
IMAGE_SYM_CLASS_WEAK_EXTERNAL = 105
IMAGE_SYM_CLASS_CLR_TOKEN = 107
IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY = 1
IMAGE_WEAK_EXTERN_SEARCH_LIBRARY = 2
IMAGE_WEAK_EXTERN_SEARCH_ALIAS = 3
COFF::
namespace COFF
if defined Settings.Machine
MACHINE := Settings.Machine
else
MACHINE := IMAGE_FILE_MACHINE_I386
end if
if defined Settings.Characteristics
CHARACTERISTICS = Settings.Characteristics
else
CHARACTERISTICS = IMAGE_FILE_32BIT_MACHINE
end if
Header:
Machine dw MACHINE
NumberOfSections dw NUMBER_OF_SECTIONS
TimeDateStamp dd __TIME__
PointerToSymbolTable dd SYMBOL_TABLE_OFFSET
NumberOfSymbols dd NUMBER_OF_SYMBOLS
SizeOfOptionalHeader dw 0
Characteristics dw CHARACTERISTICS
Sections: db NUMBER_OF_SECTIONS * sizeof IMAGE_SECTION_HEADER dup 0
virtual at 0
symbol_table:: rb NUMBER_OF_SYMBOLS * sizeof IMAGE_SYMBOL
end virtual
virtual at 0
string_table:: dd STRING_TABLE_SIZE
STRING_POSITION = $
rb STRING_TABLE_SIZE - $
end virtual
virtual at 0
relocations:: rb NUMBER_OF_RELOCATIONS * sizeof IMAGE_RELOCATION
end virtual
element relocatable?
macro section_start
local sym
element sym : relocatable * (1+SECTION_INDEX) + SYMBOL_INDEX
SECTION_BASE = sym
org sym
if DEFINED_SECTION | defined DEFAULT_SECTION
store SECTION_NAME : 8 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.ShortName
store IMAGE_SYM_CLASS_STATIC at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.StorageClass
store 1+SECTION_INDEX at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.SectionNumber
SYMBOL_INDEX = SYMBOL_INDEX + 1
end if
end macro
RELOCATION_INDEX = 0
SECTION_INDEX = 0
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
SYMBOL_INDEX = 0
SECTION_OFFSET = $%
SECTION_ALIGN = 4
SECTION_NAME = '.flat'
SECTION_FLAGS = IMAGE_SCN_CNT_CODE + IMAGE_SCN_CNT_INITIALIZED_DATA
DEFINED_SECTION = 0
section_start
end namespace
macro section?
namespace COFF
SECTION_SIZE = $% - SECTION_OFFSET
if DEFINED_SECTION | SECTION_SIZE > 0
if ~ DEFINED_SECTION
DEFAULT_SECTION := 1
end if
if $%% = SECTION_OFFSET
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_CNT_UNINITIALIZED_DATA
SECTION_OFFSET = 0
section $
else
UNINITIALIZED_LENGTH = $% - $%%
section $
db UNINITIALIZED_LENGTH dup 0
end if
if RELOCATION_INDEX > SECTION_RELOCATION_INDEX
store RELOCATIONS_OFFSET + SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.PointerToRelocations
if RELOCATION_INDEX - SECTION_RELOCATION_INDEX > 65535
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_LNK_NRELOC_OVFL
store 0FFFFh at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.NumberOfRelocations
load RELOCATIONS : (RELOCATION_INDEX - SECTION_RELOCATION_INDEX) * sizeof IMAGE_RELOCATION from relocations : SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION
store RELOCATIONS : (RELOCATION_INDEX - SECTION_RELOCATION_INDEX) * sizeof IMAGE_RELOCATION at relocations : (SECTION_RELOCATION_INDEX+1) * sizeof IMAGE_RELOCATION
RELOCATION_INDEX = RELOCATION_INDEX + 1
store RELOCATION_INDEX - SECTION_RELOCATION_INDEX at relocations : SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION + IMAGE_RELOCATION.VirtualAddress
store 0 at relocations : SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION + IMAGE_RELOCATION.SymbolTableIndex
store 0 at relocations : SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION + IMAGE_RELOCATION.Type
else
store RELOCATION_INDEX - SECTION_RELOCATION_INDEX at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.NumberOfRelocations
end if
end if
store SECTION_NAME : 8 at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.Name
store SECTION_OFFSET at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.PointerToRawData
store SECTION_SIZE at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.SizeOfRawData
store SECTION_FLAGS at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.Characteristics
SECTION_INDEX = SECTION_INDEX + 1
end if
end namespace
end macro
macro section? declaration*
namespace COFF
section
DEFINED_SECTION = 1
SECTION_FLAGS = 0
SECTION_OFFSET = $%
SECTION_ALIGN = 4
match name attributes, declaration
SECTION_NAME = name
local seq,list
match flags =align? boundary, attributes
SECTION_ALIGN = boundary
define seq flags
else match =align? boundary, attributes
SECTION_ALIGN = boundary
define seq
else
define seq attributes
end match
while 1
match car cdr, seq
define list car
define seq cdr
else
match any, seq
define list any
end match
break
end match
end while
irpv attribute, list
match =code?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_CNT_CODE
else match =data?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_CNT_INITIALIZED_DATA
else match =readable?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_READ
else match =writeable?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_WRITE
else match =executable?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_EXECUTE
else match =shareable?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_SHARED
else match =discardable?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_DISCARDABLE
else match =notpageable?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_NOT_PAGED
else match =linkremove?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_LNK_REMOVE
else match =linkinfo?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_LNK_INFO
else
err 'unknown attribute "',`attribute,'"'
end match
end irpv
else
SECTION_NAME = declaration
end match
repeat 1, i:SECTION_ALIGN
if defined IMAGE_SCN_ALIGN_#i#BYTES
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_ALIGN_#i#BYTES
else
err 'invalid section alignment'
end if
end repeat
section_start
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
end namespace
end macro
calminstruction align? boundary,value:?
check COFF.SECTION_ALIGN mod (boundary) = 0
jyes allowed
err 'section not aligned enough'
exit
allowed:
compute boundary, (boundary-1)-($-COFF.SECTION_BASE+boundary-1) mod boundary
arrange value, =db boundary =dup value
assemble value
end calminstruction
macro public? declaration*
namespace COFF
match =static? value =as? str, declaration
SYMBOL_VALUE = value
SYMBOL_NAME = string str
SYMBOL_CLASS = IMAGE_SYM_CLASS_STATIC
else match value =as? str, declaration
SYMBOL_VALUE = value
SYMBOL_NAME = string str
SYMBOL_CLASS = IMAGE_SYM_CLASS_EXTERNAL
else match =static? value, declaration
SYMBOL_VALUE = value
SYMBOL_NAME = `value
SYMBOL_CLASS = IMAGE_SYM_CLASS_STATIC
else
SYMBOL_VALUE = declaration
SYMBOL_NAME = `declaration
SYMBOL_CLASS = IMAGE_SYM_CLASS_EXTERNAL
end match
if SYMBOL_VALUE relativeto 1 elementof SYMBOL_VALUE & 1 elementof (1 metadataof SYMBOL_VALUE) relativeto relocatable & SYMBOL_CLASS = IMAGE_SYM_CLASS_EXTERNAL
if 1 scaleof (1 metadataof SYMBOL_VALUE) > 0
SYMBOL_SECTION_INDEX = 1 scaleof (1 metadataof SYMBOL_VALUE)
SYMBOL_VALUE = SYMBOL_VALUE - 1 elementof SYMBOL_VALUE
else
SYMBOL_SECTION_INDEX = IMAGE_SYM_UNDEFINED
SYMBOL_VALUE = 0
SYMBOL_CLASS = IMAGE_SYM_CLASS_WEAK_EXTERNAL
SYMBOL_TAG = 0 scaleof (1 metadataof SYMBOL_VALUE)
end if
else
SYMBOL_SECTION_INDEX = IMAGE_SYM_ABSOLUTE
end if
if lengthof SYMBOL_NAME > 8
store 0 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Zeroes
store STRING_POSITION at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Offset
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
else
store SYMBOL_NAME : 8 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.ShortName
end if
store SYMBOL_VALUE at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Value
store SYMBOL_SECTION_INDEX at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.SectionNumber
store SYMBOL_CLASS at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.StorageClass
if SYMBOL_CLASS = IMAGE_SYM_CLASS_WEAK_EXTERNAL
store 1 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.NumberOfAuxSymbols
SYMBOL_INDEX = SYMBOL_INDEX + 1
store SYMBOL_TAG : 4 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL
store IMAGE_WEAK_EXTERN_SEARCH_ALIAS : 4 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + 4
end if
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
macro extrn? declaration*
namespace COFF
local sym,psym
element sym : relocatable * (-1) + SYMBOL_INDEX
match str =as? name:size, declaration
label name:size at sym
SYMBOL_NAME = string str
else match name:size, declaration
label name:size at sym
SYMBOL_NAME = `name
else match str =as? name, declaration
label name at sym
SYMBOL_NAME = string str
else
label declaration at sym
SYMBOL_NAME = `declaration
end match
if lengthof SYMBOL_NAME > 8
store 0 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Zeroes
store STRING_POSITION at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Offset
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
else
store SYMBOL_NAME : 8 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.ShortName
end if
store IMAGE_SYM_CLASS_EXTERNAL at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.StorageClass
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
element COFF.IMAGE_BASE
RVA? equ -COFF.IMAGE_BASE+
calminstruction calminstruction?.initsym? var*, val&
publish var, val
end calminstruction
calminstruction calminstruction?.asm? line&
local name, i
initsym name, name.0
match name.i, name
compute i, i+1
arrange name, name.i
publish name, line
arrange line, =assemble name
assemble line
end calminstruction
if COFF.MACHINE = IMAGE_FILE_MACHINE_I386
calminstruction dword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable
jyes dir32
check ~ value relativeto 0 & (value + COFF.IMAGE_BASE) relativeto 1 elementof (value + COFF.IMAGE_BASE) & 1 elementof (1 metadataof (value + COFF.IMAGE_BASE)) relativeto COFF.relocatable
jyes dir32nb
check ~ value relativeto 0 & (value + COFF.SECTION_BASE) relativeto 1 elementof (value + COFF.SECTION_BASE)
jno plain
check 1 elementof (1 metadataof (value + COFF.SECTION_BASE)) relativeto COFF.relocatable
jyes rel32
plain:
emit 4, value
exit
local offset, symndx, type
dir32:
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_I386_DIR32
jump add_relocation
dir32nb:
compute value, value + COFF.IMAGE_BASE
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_I386_DIR32NB
jump add_relocation
rel32:
compute value, value + (COFF.SECTION_BASE + $% + 4 - COFF.SECTION_OFFSET)
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_I386_REL32
jump add_relocation
add_relocation:
compute offset, $%
emit 4, 0 scaleof value
check $% > offset
jno done
compute offset, offset - COFF.SECTION_OFFSET
local relocation
compute relocation, COFF.RELOCATION_INDEX * sizeof IMAGE_RELOCATION
asm store offset at COFF.relocations : relocation + IMAGE_RELOCATION.VirtualAddress
asm store symndx at COFF.relocations : relocation + IMAGE_RELOCATION.SymbolTableIndex
asm store type at COFF.relocations : relocation + IMAGE_RELOCATION.Type
compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1
done:
end calminstruction
calminstruction qword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable
jyes dir32
check ~ value relativeto 0 & (value + COFF.IMAGE_BASE) relativeto 1 elementof (value + COFF.IMAGE_BASE) & 1 elementof (1 metadataof (value + COFF.IMAGE_BASE)) relativeto COFF.relocatable
jyes dir32nb
plain:
emit 8, value
exit
local offset, symndx, type
dir32:
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_I386_DIR32
jump add_relocation
dir32nb:
compute value, value + COFF.IMAGE_BASE
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_I386_DIR32NB
jump add_relocation
add_relocation:
compute offset, $%
emit 8, 0 scaleof value
check $% > offset
jno done
compute offset, offset - COFF.SECTION_OFFSET
local relocation
compute relocation, COFF.RELOCATION_INDEX * sizeof IMAGE_RELOCATION
asm store offset at COFF.relocations : relocation + IMAGE_RELOCATION.VirtualAddress
asm store symndx at COFF.relocations : relocation + IMAGE_RELOCATION.SymbolTableIndex
asm store type at COFF.relocations : relocation + IMAGE_RELOCATION.Type
compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1
done:
end calminstruction
else if COFF.MACHINE = IMAGE_FILE_MACHINE_AMD64
calminstruction dword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable
jyes addr32
check ~ value relativeto 0 & (value + COFF.IMAGE_BASE) relativeto 1 elementof (value + COFF.IMAGE_BASE) & 1 elementof (1 metadataof (value + COFF.IMAGE_BASE)) relativeto COFF.relocatable
jyes addr32nb
check ~ value relativeto 0 & (value + COFF.SECTION_BASE) relativeto 1 elementof (value + COFF.SECTION_BASE)
jno plain
check 1 elementof (1 metadataof (value + COFF.SECTION_BASE)) relativeto COFF.relocatable
jyes rel32
plain:
emit 4, value
exit
local offset, symndx, type
addr32:
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_AMD64_ADDR32
jump add_relocation
addr32nb:
compute value, value + COFF.IMAGE_BASE
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_AMD64_ADDR32NB
jump add_relocation
rel32:
compute value, value + (COFF.SECTION_BASE + $% + 4 - COFF.SECTION_OFFSET)
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_AMD64_REL32
jump add_relocation
add_relocation:
compute offset, $%
emit 4, 0 scaleof value
check $% > offset
jno done
compute offset, offset - COFF.SECTION_OFFSET
local relocation
compute relocation, COFF.RELOCATION_INDEX * sizeof IMAGE_RELOCATION
asm store offset at COFF.relocations : relocation + IMAGE_RELOCATION.VirtualAddress
asm store symndx at COFF.relocations : relocation + IMAGE_RELOCATION.SymbolTableIndex
asm store type at COFF.relocations : relocation + IMAGE_RELOCATION.Type
compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1
done:
end calminstruction
calminstruction qword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable
jyes addr64
check ~ value relativeto 0 & (value + COFF.IMAGE_BASE) relativeto 1 elementof (value + COFF.IMAGE_BASE) & 1 elementof (1 metadataof (value + COFF.IMAGE_BASE)) relativeto COFF.relocatable
jyes addr64nb
plain:
emit 8, value
exit
local offset, symndx, type
addr64:
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_AMD64_ADDR64
jump add_relocation
addr64nb:
compute value, value + COFF.IMAGE_BASE
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_AMD64_ADDR64NB
jump add_relocation
add_relocation:
compute offset, $%
emit 8, 0 scaleof value
check $% > offset
jno done
compute offset, offset - COFF.SECTION_OFFSET
local relocation
compute relocation, COFF.RELOCATION_INDEX * sizeof IMAGE_RELOCATION
asm store offset at COFF.relocations : relocation + IMAGE_RELOCATION.VirtualAddress
asm store symndx at COFF.relocations : relocation + IMAGE_RELOCATION.SymbolTableIndex
asm store type at COFF.relocations : relocation + IMAGE_RELOCATION.Type
compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1
done:
end calminstruction
end if
iterate <dd,dword>, dd,dword, dq,qword
calminstruction dd? definitions&
local value, n
start:
match value=,definitions, definitions, ()
jyes recognize
match value, definitions
arrange definitions,
recognize:
match n =dup? value, value, ()
jyes duplicate
match ?, value
jyes reserve
call dword, value
next:
match , definitions
jno start
take , definitions
take definitions, definitions
jyes next
exit
reserve:
emit dword
jump next
duplicate:
match (value), value
stack:
check n
jno next
take definitions, value
arrange value, definitions
compute n, n - 1
jump stack
end calminstruction
calminstruction (label) dd? definitions&
local cmd
arrange cmd, =label label : =dword
assemble cmd
arrange cmd, =dd definitions
assemble cmd
end calminstruction
end iterate
postpone
purge section?
section
namespace COFF
NUMBER_OF_SECTIONS := SECTION_INDEX
STRING_TABLE_SIZE := STRING_POSITION
NUMBER_OF_SYMBOLS := SYMBOL_INDEX
NUMBER_OF_RELOCATIONS := RELOCATION_INDEX
RELOCATIONS_OFFSET = $%
load byte_sequence : NUMBER_OF_RELOCATIONS * sizeof IMAGE_RELOCATION from relocations:0
db byte_sequence
SYMBOL_TABLE_OFFSET = $%
load byte_sequence : NUMBER_OF_SYMBOLS * sizeof IMAGE_SYMBOL from symbol_table:0
db byte_sequence
load byte_sequence : STRING_TABLE_SIZE from string_table:0
db byte_sequence
end namespace
end postpone

View File

@ -0,0 +1,640 @@
macro struct? name
macro end?.struct?!
end namespace
esc end struc
virtual at 0
name name
sizeof.name = $
end virtual
purge end?.struct?
end macro
esc struc name
label . : sizeof.name
namespace .
end macro
struct Elf32_Shdr
sh_name dd ?
sh_type dd ?
sh_flags dd ?
sh_addr dd ?
sh_offset dd ?
sh_size dd ?
sh_link dd ?
sh_info dd ?
sh_addralign dd ?
sh_entsize dd ?
end struct
struct Elf32_Sym
st_name dd ?
st_value dd ?
st_size dd ?
st_info db ?
st_other db ?
st_shndx dw ?
end struct
struct Elf32_Rel
r_offset dd ?
r_info dd ?
end struct
struct Elf32_Rela
r_offset dd ?
r_info dd ?
r_addend dd ?
end struct
struct Elf32_Phdr
p_type dd ?
p_offset dd ?
p_vaddr dd ?
p_paddr dd ?
p_filesz dd ?
p_memsz dd ?
p_flags dd ?
p_align dd ?
end struct
purge struct?
ELFCLASSNONE = 0
ELFCLASS32 = 1
ELFCLASS64 = 2
ELFDATANONE = 0
ELFDATA2LSB = 1
ELFDATA2MSB = 2
ELFOSABI_NONE = 0
ELFOSABI_HPUX = 1
ELFOSABI_NETBSD = 2
ELFOSABI_GNU = 3
ELFOSABI_LINUX = 3
ELFOSABI_SOLARIS = 6
ELFOSABI_AIX = 7
ELFOSABI_IRIX = 8
ELFOSABI_FREEBSD = 9
ELFOSABI_TRU64 = 10
ELFOSABI_MODESTO = 11
ELFOSABI_OPENBSD = 12
ELFOSABI_OPENVMS = 13
ELFOSABI_NSK = 14
ELFOSABI_AROS = 15
ELFOSABI_FENIXOS = 16
ELFOSABI_CLOUDABI = 17
ELFOSABI_OPENVOS = 18
ET_NONE = 0
ET_REL = 1
ET_EXEC = 2
ET_DYN = 3
ET_CORE = 4
ET_LOPROC = 0xff00
ET_HIPROC = 0xffff
EM_NONE = 0
EM_M32 = 1
EM_SPARC = 2
EM_386 = 3
EM_68K = 4
EM_88K = 5
EM_860 = 7
EM_MIPS = 8
EM_X86_64 = 62
EV_NONE = 0
EV_CURRENT = 1
SHN_UNDEF = 0
SHN_LORESERVE = 0xff00
SHN_LOPROC = 0xff00
SHN_HIPROC = 0xff1f
SHN_ABS = 0xfff1
SHN_COMMON = 0xfff2
SHN_HIRESERVE = 0xffff
SHT_NULL = 0
SHT_PROGBITS = 1
SHT_SYMTAB = 2
SHT_STRTAB = 3
SHT_RELA = 4
SHT_HASH = 5
SHT_DYNAMIC = 6
SHT_NOTE = 7
SHT_NOBITS = 8
SHT_REL = 9
SHT_SHLIB = 10
SHT_DYNSYM = 11
SHT_LOPROC = 0x70000000
SHT_HIPROC = 0x7fffffff
SHT_LOUSER = 0x80000000
SHT_HIUSER = 0xffffffff
SHF_WRITE = 0x1
SHF_ALLOC = 0x2
SHF_EXECINSTR = 0x4
SHF_MASKPROC = 0xf0000000
STT_NOTYPE = 0
STT_OBJECT = 1
STT_FUNC = 2
STT_SECTION = 3
STT_FILE = 4
STT_LOPROC = 13
STT_HIPROC = 15
STB_LOCAL = 0
STB_GLOBAL = 1
STB_WEAK = 2
STB_LOPROC = 13
STB_HIPROC = 15
R_386_NONE = 0
R_386_32 = 1
R_386_PC32 = 2
R_386_GOT32 = 3
R_386_PLT32 = 4
R_386_COPY = 5
R_386_GLOB_DAT = 6
R_386_JMP_SLOT = 7
R_386_RELATIVE = 8
R_386_GOTOFF = 9
R_386_GOTPC = 10
R_X86_64_NONE = 0
R_X86_64_64 = 1
R_X86_64_PC32 = 2
R_X86_64_GOT32 = 3
R_X86_64_PLT32 = 4
R_X86_64_COPY = 5
R_X86_64_GLOB_DAT = 6
R_X86_64_JUMP_SLOT = 7
R_X86_64_RELATIVE = 8
R_X86_64_GOTPCREL = 9
R_X86_64_32 = 10
R_X86_64_32S = 11
R_X86_64_16 = 12
R_X86_64_PC16 = 13
R_X86_64_8 = 14
R_X86_64_PC8 = 15
R_X86_64_DPTMOD64 = 16
R_X86_64_DTPOFF64 = 17
R_X86_64_TPOFF64 = 18
R_X86_64_TLSGD = 19
R_X86_64_TLSLD = 20
R_X86_64_DTPOFF32 = 21
R_X86_64_GOTTPOFF = 22
R_X86_64_TPOFF32 = 23
R_X86_64_PC64 = 24
R_X86_64_GOTOFF64 = 25
R_X86_64_GOTPC32 = 26
ELF::
namespace ELF
if defined Settings.Machine
MACHINE := Settings.Machine
else
MACHINE := EM_386
end if
if defined Settings.ABI
ABI := Settings.ABI
else
ABI := ELFOSABI_NONE
end if
if MACHINE = EM_386
R_32 = R_386_32
R_PC32 = R_386_PC32
R_GOTOFF = R_386_GOTOFF
R_PLT32 = R_386_PLT32
else if MACHINE = EM_X86_64
R_32 = R_X86_64_32
R_PC32 = R_X86_64_PC32
R_PLT32 = R_X86_64_PLT32
end if
Header:
e_ident db 0x7F,'ELF',ELFCLASS32,ELFDATA2LSB,EV_CURRENT,ABI,(16-$) dup 0
e_type dw ET_REL
e_machine dw MACHINE
e_version dd EV_CURRENT
e_entry dd 0
e_phoff dd 0
e_shoff dd SECTION_TABLE_OFFSET
e_flags dd 0
e_ehsize dw Content
e_phentsize dw 0
e_phnum dw 0
e_shentsize dw sizeof Elf32_Shdr
e_shnum dw NUMBER_OF_SECTIONS
e_shstrndx dw STRING_TABLE_SECTION_INDEX
Content:
virtual at 0
section_table:: rb NUMBER_OF_SECTIONS * sizeof Elf32_Shdr
end virtual
virtual at 0
symbol_table:: rb NUMBER_OF_SYMBOLS * sizeof Elf32_Sym
end virtual
virtual at 0
string_table::
_null db 0
_symtab db '.symtab',0
_strtab db '.strtab',0
SECTION_NAME_POSITION = $
rb SECTION_NAME_TABLE_SIZE - $
STRING_POSITION = $
rb STRING_TABLE_SIZE - $
end virtual
virtual at 0
relocations:: rb NUMBER_OF_RELOCATIONS * sizeof Elf32_Rel
end virtual
element relocatable?
macro section_org
local sym
element sym : relocatable * SECTION_INDEX + SECTION_SYMBOL_INDEX
SECTION_BASE = sym
org sym
end macro
RELOCATION_INDEX = 0
SECTION_INDEX = 1
SECTION_SYMBOL_INDEX = SECTION_INDEX
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
SYMBOL_INDEX = NUMBER_OF_SECTION_SYMBOLS
SECTION_OFFSET = $%
SECTION_ALIGN = 4
SECTION_NAME = '.flat'
SECTION_FLAGS = SHF_ALLOC + SHF_WRITE + SHF_EXECINSTR
DEFINED_SECTION = 0
section_org
end namespace
macro section?
namespace ELF
SECTION_SIZE = $% - SECTION_OFFSET
if DEFINED_SECTION | SECTION_SIZE > 0
store SECTION_OFFSET at section_table : Elf32_Shdr.sh_offset + SECTION_INDEX * sizeof Elf32_Shdr
store SECTION_SIZE at section_table : Elf32_Shdr.sh_size + SECTION_INDEX * sizeof Elf32_Shdr
store SECTION_ALIGN at section_table : Elf32_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf32_Shdr
store SECTION_FLAGS at section_table : Elf32_Shdr.sh_flags + SECTION_INDEX * sizeof Elf32_Shdr
if $%% = SECTION_OFFSET
store SHT_NOBITS at section_table : Elf32_Shdr.sh_type + SECTION_INDEX * sizeof Elf32_Shdr
section $
else
store SHT_PROGBITS at section_table : Elf32_Shdr.sh_type + SECTION_INDEX * sizeof Elf32_Shdr
UNINITIALIZED_LENGTH = $% - $%%
section $
db UNINITIALIZED_LENGTH dup 0
end if
store SECTION_INDEX at symbol_table : Elf32_Sym.st_shndx + SECTION_SYMBOL_INDEX * sizeof Elf32_Sym
store STT_SECTION + STB_LOCAL shl 4 at symbol_table : Elf32_Sym.st_info + SECTION_SYMBOL_INDEX * sizeof Elf32_Sym
if RELOCATION_INDEX > SECTION_RELOCATION_INDEX
store RELOCATIONS_OFFSET + SECTION_RELOCATION_INDEX * sizeof Elf32_Rel at section_table : Elf32_Shdr.sh_offset + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store (RELOCATION_INDEX - SECTION_RELOCATION_INDEX) * sizeof Elf32_Rel at section_table : Elf32_Shdr.sh_size + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store SHT_REL at section_table : Elf32_Shdr.sh_type + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store SYMBOL_TABLE_SECTION_INDEX at section_table : Elf32_Shdr.sh_link + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store SECTION_INDEX at section_table : Elf32_Shdr.sh_info + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store sizeof Elf32_Rel at section_table : Elf32_Shdr.sh_entsize + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store 4 at section_table : Elf32_Shdr.sh_addralign + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store SECTION_NAME_POSITION at section_table : Elf32_Shdr.sh_name + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store SECTION_NAME_POSITION + 4 at section_table : Elf32_Shdr.sh_name + SECTION_INDEX * sizeof Elf32_Shdr
store SECTION_NAME_POSITION + 4 at symbol_table : Elf32_Sym.st_name + SECTION_SYMBOL_INDEX * sizeof Elf32_Sym
store '.rel' + SECTION_NAME shl (4*8) : 4 + lengthof (string SECTION_NAME) at string_table:SECTION_NAME_POSITION
SECTION_NAME_POSITION = SECTION_NAME_POSITION + 4 + lengthof (string SECTION_NAME) + 1
SECTION_INDEX = SECTION_INDEX + 2
SECTION_SYMBOL_INDEX = SECTION_SYMBOL_INDEX + 1
else
store SECTION_NAME_POSITION at section_table : Elf32_Shdr.sh_name + SECTION_INDEX * sizeof Elf32_Shdr
store SECTION_NAME_POSITION at symbol_table : Elf32_Sym.st_name + SECTION_SYMBOL_INDEX * sizeof Elf32_Sym
store SECTION_NAME : lengthof (string SECTION_NAME) at string_table:SECTION_NAME_POSITION
SECTION_NAME_POSITION = SECTION_NAME_POSITION + lengthof (string SECTION_NAME) + 1
SECTION_INDEX = SECTION_INDEX + 1
SECTION_SYMBOL_INDEX = SECTION_SYMBOL_INDEX + 1
end if
end if
end namespace
end macro
macro section? declaration*
namespace ELF
section
DEFINED_SECTION = 1
SECTION_FLAGS = SHF_ALLOC
SECTION_OFFSET = $%
SECTION_ALIGN = 4
match name attributes, declaration
SECTION_NAME = name
local seq,list
match flags =align? boundary, attributes
SECTION_ALIGN = boundary
define seq flags
else match =align? boundary, attributes
SECTION_ALIGN = boundary
define seq
else
define seq attributes
end match
while 1
match car cdr, seq
define list car
define seq cdr
else
match any, seq
define list any
end match
break
end match
end while
irpv attribute, list
match =writeable?, attribute
SECTION_FLAGS = SECTION_FLAGS or SHF_WRITE
else match =executable?, attribute
SECTION_FLAGS = SECTION_FLAGS or SHF_EXECINSTR
else
err 'unknown attribute "',`attribute,'"'
end match
end irpv
else
SECTION_NAME = declaration
end match
section_org
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
end namespace
end macro
calminstruction align? boundary,value:?
check ELF.SECTION_ALIGN mod (boundary) = 0
jyes allowed
err 'section not aligned enough'
exit
allowed:
compute boundary, (boundary-1)-($-ELF.SECTION_BASE+boundary-1) mod boundary
arrange value, =db boundary =dup value
assemble value
end calminstruction
macro public? declaration*
namespace ELF
match value =as? str, declaration
SYMBOL_VALUE = value
SYMBOL_SIZE = sizeof value
SYMBOL_NAME = string str
else
SYMBOL_VALUE = declaration
SYMBOL_SIZE = sizeof declaration
SYMBOL_NAME = `declaration
end match
if SYMBOL_VALUE relativeto 1 elementof SYMBOL_VALUE & 1 elementof (1 metadataof SYMBOL_VALUE) relativeto relocatable & 1 scaleof (1 metadataof SYMBOL_VALUE) > 0
SYMBOL_SECTION_INDEX = 1 scaleof (1 metadataof SYMBOL_VALUE)
SYMBOL_VALUE = SYMBOL_VALUE - 1 elementof SYMBOL_VALUE
else
SYMBOL_SECTION_INDEX = SHN_ABS
end if
store STRING_POSITION at symbol_table : Elf32_Sym.st_name + SYMBOL_INDEX * sizeof Elf32_Sym
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
store SYMBOL_VALUE at symbol_table : Elf32_Sym.st_value + SYMBOL_INDEX * sizeof Elf32_Sym
store SYMBOL_SIZE at symbol_table : Elf32_Sym.st_size + SYMBOL_INDEX * sizeof Elf32_Sym
store SYMBOL_SECTION_INDEX at symbol_table : Elf32_Sym.st_shndx + SYMBOL_INDEX * sizeof Elf32_Sym
if SYMBOL_SIZE
store STT_OBJECT + STB_GLOBAL shl 4 at symbol_table : Elf32_Sym.st_info + SYMBOL_INDEX * sizeof Elf32_Sym
else
store STT_FUNC + STB_GLOBAL shl 4 at symbol_table : Elf32_Sym.st_info + SYMBOL_INDEX * sizeof Elf32_Sym
end if
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
macro extrn? declaration*
namespace ELF
local sym,psym
element sym : relocatable * (-1) + SYMBOL_INDEX
element psym : PLT + SYMBOL_INDEX
match str =as? name:size, declaration
label name:size at sym
label PLT.name at psym
SYMBOL_NAME = string str
SYMBOL_SIZE = size
else match name:size, declaration
label name:size at sym
label PLT.name at psym
SYMBOL_NAME = `name
SYMBOL_SIZE = size
else match str =as? name, declaration
label name at sym
label PLT.name at psym
SYMBOL_NAME = string str
SYMBOL_SIZE = 0
else
label declaration at sym
label PLT.declaration at psym
SYMBOL_NAME = `declaration
SYMBOL_SIZE = 0
end match
store STRING_POSITION at symbol_table : Elf32_Sym.st_name + SYMBOL_INDEX * sizeof Elf32_Sym
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
store SYMBOL_SIZE at symbol_table : Elf32_Sym.st_size + SYMBOL_INDEX * sizeof Elf32_Sym
store STT_NOTYPE + STB_GLOBAL shl 4 at symbol_table : Elf32_Sym.st_info + SYMBOL_INDEX * sizeof Elf32_Sym
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
element _GLOBAL_OFFSET_TABLE_
RVA? equ -_GLOBAL_OFFSET_TABLE_+
element PLT?
calminstruction calminstruction?.initsym? var*, val&
publish var, val
end calminstruction
calminstruction calminstruction?.asm? line&
local name, i
initsym name, name.0
match name.i, name
compute i, i+1
arrange name, name.i
publish name, line
arrange line, =assemble name
assemble line
end calminstruction
calminstruction dword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto ELF.relocatable
jyes r_32
check ~ value relativeto 0 & (value + _GLOBAL_OFFSET_TABLE_) relativeto 1 elementof (value + _GLOBAL_OFFSET_TABLE_) & 1 elementof (1 metadataof (value + _GLOBAL_OFFSET_TABLE_)) relativeto ELF.relocatable
jyes r_gotoff
check ~ value relativeto 0 & (value + ELF.SECTION_BASE) relativeto 1 elementof (value + ELF.SECTION_BASE)
jno plain
check 1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto ELF.relocatable
jyes r_pc32
check 1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto PLT
jyes r_plt32
plain:
emit 4, value
exit
local offset, info
r_32:
compute info, ELF.R_32 + (0 scaleof (1 metadataof value)) shl 8
jump add_relocation
r_gotoff:
compute value, value + _GLOBAL_OFFSET_TABLE_
compute info, ELF.R_GOTOFF + (0 scaleof (1 metadataof value)) shl 8
jump add_relocation
r_pc32:
compute value, value + (ELF.SECTION_BASE + $% - ELF.SECTION_OFFSET)
compute info, ELF.R_PC32 + (0 scaleof (1 metadataof value)) shl 8
jump add_relocation
r_plt32:
compute value, value + (ELF.SECTION_BASE + $% - ELF.SECTION_OFFSET)
compute info, ELF.R_PLT32 + (0 scaleof (1 metadataof value)) shl 8
jump add_relocation
add_relocation:
compute offset, $%
emit 4, 0 scaleof value
check $% > offset
jno done
compute offset, offset - ELF.SECTION_OFFSET
local Rel
compute Rel, ELF.RELOCATION_INDEX * sizeof Elf32_Rel
asm store offset at ELF.relocations : Rel + Elf32_Rel.r_offset
asm store info at ELF.relocations : Rel + Elf32_Rel.r_info
compute ELF.RELOCATION_INDEX, ELF.RELOCATION_INDEX + 1
done:
end calminstruction
calminstruction dd? definitions&
local value, n
start:
match value=,definitions, definitions, ()
jyes recognize
match value, definitions
arrange definitions,
recognize:
match n =dup? value, value, ()
jyes duplicate
match ?, value
jyes reserve
call dword, value
next:
match , definitions
jno start
take , definitions
take definitions, definitions
jyes next
exit
reserve:
emit dword
jump next
duplicate:
match (value), value
stack:
check n
jno next
take definitions, value
arrange value, definitions
compute n, n - 1
jump stack
end calminstruction
calminstruction (label) dd? definitions&
local cmd
arrange cmd, =label label : =dword
assemble cmd
arrange cmd, =dd definitions
assemble cmd
end calminstruction
postpone
purge section?
section
namespace ELF
SECTION_NAME_TABLE_SIZE := SECTION_NAME_POSITION
STRING_TABLE_SIZE := STRING_POSITION
NUMBER_OF_SECTION_SYMBOLS := SECTION_SYMBOL_INDEX
NUMBER_OF_SYMBOLS := SYMBOL_INDEX
SYMBOL_TABLE_SIZE := NUMBER_OF_SYMBOLS * sizeof Elf32_Sym
NUMBER_OF_RELOCATIONS := RELOCATION_INDEX
rb (-$%) and 11b
RELOCATIONS_OFFSET = $%
load byte_sequence : NUMBER_OF_RELOCATIONS * sizeof Elf32_Rel from relocations:0
db byte_sequence
store _symtab at section_table : Elf32_Shdr.sh_name + SECTION_INDEX * sizeof Elf32_Shdr
store $% at section_table : Elf32_Shdr.sh_offset + SECTION_INDEX * sizeof Elf32_Shdr
store SYMBOL_TABLE_SIZE at section_table : Elf32_Shdr.sh_size + SECTION_INDEX * sizeof Elf32_Shdr
store sizeof Elf32_Sym at section_table : Elf32_Shdr.sh_entsize + SECTION_INDEX * sizeof Elf32_Shdr
store 4 at section_table : Elf32_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf32_Shdr
store SHT_SYMTAB at section_table : Elf32_Shdr.sh_type + SECTION_INDEX * sizeof Elf32_Shdr
store STRING_TABLE_SECTION_INDEX at section_table : Elf32_Shdr.sh_link + SECTION_INDEX * sizeof Elf32_Shdr
store NUMBER_OF_SECTION_SYMBOLS at section_table : Elf32_Shdr.sh_info + SECTION_INDEX * sizeof Elf32_Shdr
SYMBOL_TABLE_SECTION_INDEX := SECTION_INDEX
load byte_sequence : SYMBOL_TABLE_SIZE from symbol_table:0
db byte_sequence
SECTION_INDEX = SECTION_INDEX + 1
store _strtab at section_table : Elf32_Shdr.sh_name + SECTION_INDEX * sizeof Elf32_Shdr
store $% at section_table : Elf32_Shdr.sh_offset + SECTION_INDEX * sizeof Elf32_Shdr
store STRING_TABLE_SIZE at section_table : Elf32_Shdr.sh_size + SECTION_INDEX * sizeof Elf32_Shdr
store 1 at section_table : Elf32_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf32_Shdr
store SHT_STRTAB at section_table : Elf32_Shdr.sh_type + SECTION_INDEX * sizeof Elf32_Shdr
STRING_TABLE_SECTION_INDEX := SECTION_INDEX
load byte_sequence : STRING_TABLE_SIZE from string_table:0
db byte_sequence
SECTION_INDEX = SECTION_INDEX + 1
assert SECTION_INDEX <= SHN_LORESERVE
NUMBER_OF_SECTIONS := SECTION_INDEX
rb (-$%) and 11b
SECTION_TABLE_OFFSET := $%
load byte_sequence : NUMBER_OF_SECTIONS * sizeof Elf32_Shdr from section_table:0
db byte_sequence
end namespace
end postpone

View File

@ -0,0 +1,652 @@
macro struct? name
macro end?.struct?!
end namespace
esc end struc
virtual at 0
name name
sizeof.name = $
end virtual
purge end?.struct?
end macro
esc struc name
label . : sizeof.name
namespace .
end macro
struct Elf64_Shdr
sh_name dd ?
sh_type dd ?
sh_flags dq ?
sh_addr dq ?
sh_offset dq ?
sh_size dq ?
sh_link dd ?
sh_info dd ?
sh_addralign dq ?
sh_entsize dq ?
end struct
struct Elf64_Sym
st_name dd ?
st_info db ?
st_other db ?
st_shndx dw ?
st_value dq ?
st_size dq ?
end struct
struct Elf64_Rel
r_offset dq ?
r_info dq ?
end struct
struct Elf64_Rela
r_offset dq ?
r_info dq ?
r_addend dq ?
end struct
struct Elf64_Phdr
p_type dd ?
p_flags dd ?
p_offset dq ?
p_vaddr dq ?
p_paddr dq ?
p_filesz dq ?
p_memsz dq ?
p_align dq ?
end struct
purge struct?
ELFCLASSNONE = 0
ELFCLASS32 = 1
ELFCLASS64 = 2
ELFDATANONE = 0
ELFDATA2LSB = 1
ELFDATA2MSB = 2
ELFOSABI_NONE = 0
ELFOSABI_HPUX = 1
ELFOSABI_NETBSD = 2
ELFOSABI_GNU = 3
ELFOSABI_LINUX = 3
ELFOSABI_SOLARIS = 6
ELFOSABI_AIX = 7
ELFOSABI_IRIX = 8
ELFOSABI_FREEBSD = 9
ELFOSABI_TRU64 = 10
ELFOSABI_MODESTO = 11
ELFOSABI_OPENBSD = 12
ELFOSABI_OPENVMS = 13
ELFOSABI_NSK = 14
ELFOSABI_AROS = 15
ELFOSABI_FENIXOS = 16
ELFOSABI_CLOUDABI = 17
ELFOSABI_OPENVOS = 18
ET_NONE = 0
ET_REL = 1
ET_EXEC = 2
ET_DYN = 3
ET_CORE = 4
ET_LOPROC = 0xff00
ET_HIPROC = 0xffff
EM_NONE = 0
EM_IA_64 = 50
EM_X86_64 = 62
EV_NONE = 0
EV_CURRENT = 1
SHN_UNDEF = 0
SHN_LORESERVE = 0xff00
SHN_LOPROC = 0xff00
SHN_HIPROC = 0xff1f
SHN_ABS = 0xfff1
SHN_COMMON = 0xfff2
SHN_HIRESERVE = 0xffff
SHT_NULL = 0
SHT_PROGBITS = 1
SHT_SYMTAB = 2
SHT_STRTAB = 3
SHT_RELA = 4
SHT_HASH = 5
SHT_DYNAMIC = 6
SHT_NOTE = 7
SHT_NOBITS = 8
SHT_REL = 9
SHT_SHLIB = 10
SHT_DYNSYM = 11
SHT_LOPROC = 0x70000000
SHT_HIPROC = 0x7fffffff
SHT_LOUSER = 0x80000000
SHT_HIUSER = 0xffffffff
SHF_WRITE = 0x1
SHF_ALLOC = 0x2
SHF_EXECINSTR = 0x4
SHF_MASKPROC = 0xf0000000
STT_NOTYPE = 0
STT_OBJECT = 1
STT_FUNC = 2
STT_SECTION = 3
STT_FILE = 4
STT_LOPROC = 13
STT_HIPROC = 15
STB_LOCAL = 0
STB_GLOBAL = 1
STB_WEAK = 2
STB_LOPROC = 13
STB_HIPROC = 15
R_X86_64_NONE = 0
R_X86_64_64 = 1
R_X86_64_PC32 = 2
R_X86_64_GOT32 = 3
R_X86_64_PLT32 = 4
R_X86_64_COPY = 5
R_X86_64_GLOB_DAT = 6
R_X86_64_JUMP_SLOT = 7
R_X86_64_RELATIVE = 8
R_X86_64_GOTPCREL = 9
R_X86_64_32 = 10
R_X86_64_32S = 11
R_X86_64_16 = 12
R_X86_64_PC16 = 13
R_X86_64_8 = 14
R_X86_64_PC8 = 15
R_X86_64_DPTMOD64 = 16
R_X86_64_DTPOFF64 = 17
R_X86_64_TPOFF64 = 18
R_X86_64_TLSGD = 19
R_X86_64_TLSLD = 20
R_X86_64_DTPOFF32 = 21
R_X86_64_GOTTPOFF = 22
R_X86_64_TPOFF32 = 23
R_X86_64_PC64 = 24
R_X86_64_GOTOFF64 = 25
R_X86_64_GOTPC32 = 26
ELF::
namespace ELF
if defined Settings.Machine
MACHINE := Settings.Machine
else
MACHINE := EM_X86_64
end if
if defined Settings.ABI
ABI := Settings.ABI
else
ABI := ELFOSABI_NONE
end if
if MACHINE = EM_X86_64
R_64 = R_X86_64_64
R_32 = R_X86_64_32S
R_PC32 = R_X86_64_PC32
R_PLT32 = R_X86_64_PLT32
end if
Header:
e_ident db 0x7F,'ELF',ELFCLASS64,ELFDATA2LSB,EV_CURRENT,ABI,(16-$) dup 0
e_type dw ET_REL
e_machine dw MACHINE
e_version dd EV_CURRENT
e_entry dq 0
e_phoff dq 0
e_shoff dq SECTION_TABLE_OFFSET
e_flags dd 0
e_ehsize dw Content
e_phentsize dw 0
e_phnum dw 0
e_shentsize dw sizeof Elf64_Shdr
e_shnum dw NUMBER_OF_SECTIONS
e_shstrndx dw STRING_TABLE_SECTION_INDEX
Content:
virtual at 0
section_table:: rb NUMBER_OF_SECTIONS * sizeof Elf64_Shdr
end virtual
virtual at 0
symbol_table:: rb NUMBER_OF_SYMBOLS * sizeof Elf64_Sym
end virtual
virtual at 0
string_table::
_null db 0
_symtab db '.symtab',0
_strtab db '.strtab',0
SECTION_NAME_POSITION = $
rb SECTION_NAME_TABLE_SIZE - $
STRING_POSITION = $
rb STRING_TABLE_SIZE - $
end virtual
virtual at 0
relocations:: rb NUMBER_OF_RELOCATIONS * sizeof Elf64_Rela
end virtual
element relocatable?
macro section_org
local sym
element sym : relocatable * SECTION_INDEX + SECTION_SYMBOL_INDEX
SECTION_BASE = sym
org sym
end macro
RELOCATION_INDEX = 0
SECTION_INDEX = 1
SECTION_SYMBOL_INDEX = SECTION_INDEX
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
SYMBOL_INDEX = NUMBER_OF_SECTION_SYMBOLS
SECTION_OFFSET = $%
SECTION_ALIGN = 8
SECTION_NAME = '.flat'
SECTION_FLAGS = SHF_ALLOC + SHF_WRITE + SHF_EXECINSTR
DEFINED_SECTION = 0
section_org
end namespace
macro section?
namespace ELF
SECTION_SIZE = $% - SECTION_OFFSET
if DEFINED_SECTION | SECTION_SIZE > 0
store SECTION_OFFSET at section_table : Elf64_Shdr.sh_offset + SECTION_INDEX * sizeof Elf64_Shdr
store SECTION_SIZE at section_table : Elf64_Shdr.sh_size + SECTION_INDEX * sizeof Elf64_Shdr
store SECTION_ALIGN at section_table : Elf64_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf64_Shdr
store SECTION_FLAGS at section_table : Elf64_Shdr.sh_flags + SECTION_INDEX * sizeof Elf64_Shdr
if $%% = SECTION_OFFSET
store SHT_NOBITS at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr
section $
else
store SHT_PROGBITS at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr
UNINITIALIZED_LENGTH = $% - $%%
section $
db UNINITIALIZED_LENGTH dup 0
end if
store SECTION_INDEX at symbol_table : Elf64_Sym.st_shndx + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym
store STT_SECTION + STB_LOCAL shl 4 at symbol_table : Elf64_Sym.st_info + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym
if RELOCATION_INDEX > SECTION_RELOCATION_INDEX
store RELOCATIONS_OFFSET + SECTION_RELOCATION_INDEX * sizeof Elf64_Rela at section_table : Elf64_Shdr.sh_offset + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store (RELOCATION_INDEX - SECTION_RELOCATION_INDEX) * sizeof Elf64_Rela at section_table : Elf64_Shdr.sh_size + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store SHT_RELA at section_table : Elf64_Shdr.sh_type + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store SYMBOL_TABLE_SECTION_INDEX at section_table : Elf64_Shdr.sh_link + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store SECTION_INDEX at section_table : Elf64_Shdr.sh_info + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store sizeof Elf64_Rela at section_table : Elf64_Shdr.sh_entsize + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store 8 at section_table : Elf64_Shdr.sh_addralign + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store SECTION_NAME_POSITION at section_table : Elf64_Shdr.sh_name + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store SECTION_NAME_POSITION + 5 at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr
store SECTION_NAME_POSITION + 5 at symbol_table : Elf64_Sym.st_name + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym
store '.rela' + SECTION_NAME shl (5*8) : 5 + lengthof (string SECTION_NAME) at string_table:SECTION_NAME_POSITION
SECTION_NAME_POSITION = SECTION_NAME_POSITION + 5 + lengthof (string SECTION_NAME) + 1
SECTION_INDEX = SECTION_INDEX + 2
SECTION_SYMBOL_INDEX = SECTION_SYMBOL_INDEX + 1
else
store SECTION_NAME_POSITION at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr
store SECTION_NAME_POSITION at symbol_table : Elf64_Sym.st_name + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym
store SECTION_NAME : lengthof (string SECTION_NAME) at string_table:SECTION_NAME_POSITION
SECTION_NAME_POSITION = SECTION_NAME_POSITION + lengthof (string SECTION_NAME) + 1
SECTION_INDEX = SECTION_INDEX + 1
SECTION_SYMBOL_INDEX = SECTION_SYMBOL_INDEX + 1
end if
end if
end namespace
end macro
macro section? declaration*
namespace ELF
section
DEFINED_SECTION = 1
SECTION_FLAGS = SHF_ALLOC
SECTION_OFFSET = $%
SECTION_ALIGN = 8
match name attributes, declaration
SECTION_NAME = name
local seq,list
match flags =align? boundary, attributes
SECTION_ALIGN = boundary
define seq flags
else match =align? boundary, attributes
SECTION_ALIGN = boundary
define seq
else
define seq attributes
end match
while 1
match car cdr, seq
define list car
define seq cdr
else
match any, seq
define list any
end match
break
end match
end while
irpv attribute, list
match =writeable?, attribute
SECTION_FLAGS = SECTION_FLAGS or SHF_WRITE
else match =executable?, attribute
SECTION_FLAGS = SECTION_FLAGS or SHF_EXECINSTR
else
err 'unknown attribute "',`attribute,'"'
end match
end irpv
else
SECTION_NAME = declaration
end match
section_org
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
end namespace
end macro
calminstruction align? boundary,value:?
check ELF.SECTION_ALIGN mod (boundary) = 0
jyes allowed
err 'section not aligned enough'
exit
allowed:
compute boundary, (boundary-1)-($-ELF.SECTION_BASE+boundary-1) mod boundary
arrange value, =db boundary =dup value
assemble value
end calminstruction
macro public? declaration*
namespace ELF
match value =as? str, declaration
SYMBOL_VALUE = value
SYMBOL_SIZE = sizeof value
SYMBOL_NAME = string str
else
SYMBOL_VALUE = declaration
SYMBOL_SIZE = sizeof declaration
SYMBOL_NAME = `declaration
end match
if SYMBOL_VALUE relativeto 1 elementof SYMBOL_VALUE & 1 elementof (1 metadataof SYMBOL_VALUE) relativeto relocatable & 1 scaleof (1 metadataof SYMBOL_VALUE) > 0
SYMBOL_SECTION_INDEX = 1 scaleof (1 metadataof SYMBOL_VALUE)
SYMBOL_VALUE = SYMBOL_VALUE - 1 elementof SYMBOL_VALUE
else
SYMBOL_SECTION_INDEX = SHN_ABS
end if
store STRING_POSITION at symbol_table : Elf64_Sym.st_name + SYMBOL_INDEX * sizeof Elf64_Sym
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
store SYMBOL_VALUE at symbol_table : Elf64_Sym.st_value + SYMBOL_INDEX * sizeof Elf64_Sym
store SYMBOL_SIZE at symbol_table : Elf64_Sym.st_size + SYMBOL_INDEX * sizeof Elf64_Sym
store SYMBOL_SECTION_INDEX at symbol_table : Elf64_Sym.st_shndx + SYMBOL_INDEX * sizeof Elf64_Sym
if SYMBOL_SIZE
store STT_OBJECT + STB_GLOBAL shl 4 at symbol_table : Elf64_Sym.st_info + SYMBOL_INDEX * sizeof Elf64_Sym
else
store STT_FUNC + STB_GLOBAL shl 4 at symbol_table : Elf64_Sym.st_info + SYMBOL_INDEX * sizeof Elf64_Sym
end if
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
macro extrn? declaration*
namespace ELF
local sym,psym
element sym : relocatable * (-1) + SYMBOL_INDEX
element psym : PLT + SYMBOL_INDEX
match str =as? name:size, declaration
label name:size at sym
label PLT.name at psym
SYMBOL_NAME = string str
SYMBOL_SIZE = size
else match name:size, declaration
label name:size at sym
label PLT.name at psym
SYMBOL_NAME = `name
SYMBOL_SIZE = size
else match str =as? name, declaration
label name at sym
label PLT.name at psym
SYMBOL_NAME = string str
SYMBOL_SIZE = 0
else
label declaration at sym
label PLT.declaration at psym
SYMBOL_NAME = `declaration
SYMBOL_SIZE = 0
end match
store STRING_POSITION at symbol_table : Elf64_Sym.st_name + SYMBOL_INDEX * sizeof Elf64_Sym
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
store SYMBOL_SIZE at symbol_table : Elf64_Sym.st_size + SYMBOL_INDEX * sizeof Elf64_Sym
store STT_NOTYPE + STB_GLOBAL shl 4 at symbol_table : Elf64_Sym.st_info + SYMBOL_INDEX * sizeof Elf64_Sym
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
element PLT?
calminstruction calminstruction?.initsym? var*, val&
publish var, val
end calminstruction
calminstruction calminstruction?.asm? line&
local name, i
initsym name, name.0
match name.i, name
compute i, i+1
arrange name, name.i
publish name, line
arrange line, =assemble name
assemble line
end calminstruction
calminstruction dword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto ELF.relocatable
jyes r_32
check ~ value relativeto 0 & (value + ELF.SECTION_BASE) relativeto 1 elementof (value + ELF.SECTION_BASE)
jno plain
check 1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto ELF.relocatable
jyes r_pc32
check 1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto PLT
jyes r_plt32
plain:
emit 4, value
exit
local offset, addend, info
r_32:
compute offset, $%
emit 4
check $% > offset
jno done
compute offset, offset - ELF.SECTION_OFFSET
compute addend, 0 scaleof value
compute info, ELF.R_32 + (0 scaleof (1 metadataof value)) shl 32
jump add_relocation
r_pc32:
compute offset, $%
emit 4
check $% > offset
jno done
compute offset, offset - ELF.SECTION_OFFSET
compute addend, 0 scaleof (value + ELF.SECTION_BASE + offset)
compute info, ELF.R_PC32 + (0 scaleof (1 metadataof value)) shl 32
jump add_relocation
r_plt32:
compute offset, $%
emit 4
check $% > offset
jno done
compute offset, offset - ELF.SECTION_OFFSET
compute addend, 0 scaleof (value + ELF.SECTION_BASE + offset)
compute info, ELF.R_PLT32 + (0 scaleof (1 metadataof value)) shl 32
jump add_relocation
add_relocation:
local Rela
compute Rela, ELF.RELOCATION_INDEX * sizeof Elf64_Rela
asm store offset at ELF.relocations : Rela + Elf64_Rela.r_offset
asm store addend at ELF.relocations : Rela + Elf64_Rela.r_addend
asm store info at ELF.relocations : Rela + Elf64_Rela.r_info
compute ELF.RELOCATION_INDEX, ELF.RELOCATION_INDEX + 1
done:
end calminstruction
calminstruction qword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto ELF.relocatable
jyes r_64
plain:
emit 8, value
exit
local offset, addend, info
r_64:
compute offset, $%
emit 8
check $% > offset
jno done
compute offset, offset - ELF.SECTION_OFFSET
compute addend, 0 scaleof value
compute info, ELF.R_64 + (0 scaleof (1 metadataof value)) shl 32
add_relocation:
local Rela
compute Rela, ELF.RELOCATION_INDEX * sizeof Elf64_Rela
asm store offset at ELF.relocations : Rela + Elf64_Rela.r_offset
asm store addend at ELF.relocations : Rela + Elf64_Rela.r_addend
asm store info at ELF.relocations : Rela + Elf64_Rela.r_info
compute ELF.RELOCATION_INDEX, ELF.RELOCATION_INDEX + 1
done:
end calminstruction
iterate <dd,dword>, dd,dword, dq,qword
calminstruction dd? definitions&
local value, n
start:
match value=,definitions, definitions, ()
jyes recognize
match value, definitions
arrange definitions,
recognize:
match n =dup? value, value, ()
jyes duplicate
match ?, value
jyes reserve
call dword, value
next:
match , definitions
jno start
take , definitions
take definitions, definitions
jyes next
exit
reserve:
emit dword
jump next
duplicate:
match (value), value
stack:
check n
jno next
take definitions, value
arrange value, definitions
compute n, n - 1
jump stack
end calminstruction
calminstruction (label) dd? definitions&
local cmd
arrange cmd, =label label : =dword
assemble cmd
arrange cmd, =dd definitions
assemble cmd
end calminstruction
end iterate
postpone
purge section?
section
namespace ELF
SECTION_NAME_TABLE_SIZE := SECTION_NAME_POSITION
STRING_TABLE_SIZE := STRING_POSITION
NUMBER_OF_SECTION_SYMBOLS := SECTION_SYMBOL_INDEX
NUMBER_OF_SYMBOLS := SYMBOL_INDEX
SYMBOL_TABLE_SIZE := NUMBER_OF_SYMBOLS * sizeof Elf64_Sym
NUMBER_OF_RELOCATIONS := RELOCATION_INDEX
rb (-$%) and 111b
RELOCATIONS_OFFSET = $%
load byte_sequence : NUMBER_OF_RELOCATIONS * sizeof Elf64_Rela from relocations:0
db byte_sequence
store _symtab at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr
store $% at section_table : Elf64_Shdr.sh_offset + SECTION_INDEX * sizeof Elf64_Shdr
store SYMBOL_TABLE_SIZE at section_table : Elf64_Shdr.sh_size + SECTION_INDEX * sizeof Elf64_Shdr
store sizeof Elf64_Sym at section_table : Elf64_Shdr.sh_entsize + SECTION_INDEX * sizeof Elf64_Shdr
store 8 at section_table : Elf64_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf64_Shdr
store SHT_SYMTAB at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr
store STRING_TABLE_SECTION_INDEX at section_table : Elf64_Shdr.sh_link + SECTION_INDEX * sizeof Elf64_Shdr
store NUMBER_OF_SECTION_SYMBOLS at section_table : Elf64_Shdr.sh_info + SECTION_INDEX * sizeof Elf64_Shdr
SYMBOL_TABLE_SECTION_INDEX := SECTION_INDEX
load byte_sequence : SYMBOL_TABLE_SIZE from symbol_table:0
db byte_sequence
SECTION_INDEX = SECTION_INDEX + 1
store _strtab at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr
store $% at section_table : Elf64_Shdr.sh_offset + SECTION_INDEX * sizeof Elf64_Shdr
store STRING_TABLE_SIZE at section_table : Elf64_Shdr.sh_size + SECTION_INDEX * sizeof Elf64_Shdr
store 1 at section_table : Elf64_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf64_Shdr
store SHT_STRTAB at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr
STRING_TABLE_SECTION_INDEX := SECTION_INDEX
load byte_sequence : STRING_TABLE_SIZE from string_table:0
db byte_sequence
SECTION_INDEX = SECTION_INDEX + 1
assert SECTION_INDEX <= SHN_LORESERVE
NUMBER_OF_SECTIONS := SECTION_INDEX
rb (-$%) and 111b
SECTION_TABLE_OFFSET := $%
load byte_sequence : NUMBER_OF_SECTIONS * sizeof Elf64_Shdr from section_table:0
db byte_sequence
end namespace
end postpone

View File

@ -0,0 +1,326 @@
ELFCLASSNONE = 0
ELFCLASS32 = 1
ELFCLASS64 = 2
ELFDATANONE = 0
ELFDATA2LSB = 1
ELFDATA2MSB = 2
ELFOSABI_NONE = 0
ELFOSABI_HPUX = 1
ELFOSABI_NETBSD = 2
ELFOSABI_GNU = 3
ELFOSABI_LINUX = 3
ELFOSABI_SOLARIS = 6
ELFOSABI_AIX = 7
ELFOSABI_IRIX = 8
ELFOSABI_FREEBSD = 9
ELFOSABI_TRU64 = 10
ELFOSABI_MODESTO = 11
ELFOSABI_OPENBSD = 12
ELFOSABI_OPENVMS = 13
ELFOSABI_NSK = 14
ELFOSABI_AROS = 15
ELFOSABI_FENIXOS = 16
ELFOSABI_CLOUDABI = 17
ELFOSABI_OPENVOS = 18
ET_NONE = 0
ET_REL = 1
ET_EXEC = 2
ET_DYN = 3
ET_CORE = 4
ET_LOPROC = 0xff00
ET_HIPROC = 0xffff
EM_NONE = 0
EM_M32 = 1
EM_SPARC = 2
EM_386 = 3
EM_68K = 4
EM_88K = 5
EM_860 = 7
EM_MIPS = 8
EM_X86_64 = 62
EV_NONE = 0
EV_CURRENT = 1
PT_NULL = 0
PT_LOAD = 1
PT_DYNAMIC = 2
PT_INTERP = 3
PT_NOTE = 4
PT_SHLIB = 5
PT_PHDR = 6
PT_GNU_EH_FRAME = 0x6474e550
PT_GNU_STACK = 0x6474e551
PT_GNU_RELRO = 0x6474e552
PT_LOPROC = 0x70000000
PT_HIPROC = 0x7fffffff
PF_X = 1
PF_W = 2
PF_R = 4
PF_MASKOS = 0x0ff00000
PF_MASKPROC = 0xf0000000
calminstruction align? boundary,value:?
compute boundary, (boundary-1)-($-ELF.DYNAMIC+boundary-1) mod boundary
arrange value, =db boundary =dup value
assemble value
end calminstruction
ELF::
namespace ELF
if defined Settings.Class
CLASS := Settings.Class
else
CLASS := ELFCLASS32
end if
if defined Settings.Type
TYPE := Settings.Type
else
TYPE := ET_EXEC
end if
if defined Settings.Machine
MACHINE := Settings.Machine
else
MACHINE := EM_386
end if
if defined Settings.ABI
ABI := Settings.ABI
else
ABI := ELFOSABI_NONE
end if
if TYPE = ET_DYN
element DYNAMIC
else
DYNAMIC := 0
end if
if defined Settings.BaseAddress
BASE_ADDRESS := DYNAMIC + Settings.BaseAddress
else
BASE_ADDRESS := DYNAMIC + 8048000h
end if
if defined Settings.LoadHeaders
LOAD_HEADERS := Settings.LoadHeaders
else
LOAD_HEADERS := 1
end if
Header:
e_ident db 0x7F,'ELF',CLASS,ELFDATA2LSB,EV_CURRENT,ABI,(16-$) dup 0
e_type dw TYPE
e_machine dw MACHINE
e_version dd EV_CURRENT
if CLASS <> ELFCLASS64
e_entry dd start - DYNAMIC
e_phoff dd ProgramHeader
e_shoff dd 0
e_flags dd 0
e_ehsize dw ProgramHeader
e_phentsize dw SEGMENT_HEADER_LENGTH
e_phnum dw NUMBER_OF_SEGMENTS
e_shentsize dw 28h
e_shnum dw 0
e_shstrndx dw 0
else
e_entry dq start - DYNAMIC
e_phoff dq ProgramHeader
e_shoff dq 0
e_flags dd 0
e_ehsize dw ProgramHeader
e_phentsize dw SEGMENT_HEADER_LENGTH
e_phnum dw NUMBER_OF_SEGMENTS
e_shentsize dw 40h
e_shnum dw 0
e_shstrndx dw 0
end if
ProgramHeader:
if CLASS <> ELFCLASS64
p_type dd PT_LOAD
p_offset dd 0
p_vaddr dd BASE_ADDRESS - DYNAMIC
p_paddr dd BASE_ADDRESS - DYNAMIC
p_filesz dd 0
p_memsz dd 0
p_flags dd PF_R+PF_W+PF_X
p_align dd 1000h
else
p_type dd PT_LOAD
p_flags dd PF_R+PF_W+PF_X
p_offset dq 0
p_vaddr dq BASE_ADDRESS - DYNAMIC
p_paddr dq BASE_ADDRESS - DYNAMIC
p_filesz dq 0
p_memsz dq 0
p_align dq 1000h
end if
SEGMENT_HEADER_LENGTH = $ - ProgramHeader
db (NUMBER_OF_SEGMENTS-1)*SEGMENT_HEADER_LENGTH dup 0
HEADERS_OFFSET = 0
HEADERS_BASE = BASE_ADDRESS
OVERLAY_HEADERS = LOAD_HEADERS
SEGMENT_INDEX = 0
DEFINED_SEGMENT = 0
SEGMENT_TYPE = PT_LOAD
FILE_OFFSET = $%
SEGMENT_BASE = BASE_ADDRESS + FILE_OFFSET and 0FFFh
org SEGMENT_BASE
start:
end namespace
RVA? equ -ELF.BASE_ADDRESS +
macro entry? address*
namespace ELF
store address-DYNAMIC at ELF:e_entry
end namespace
end macro
macro segment?
namespace ELF
DEFINED_SEGMENT_SIZE = $ - SEGMENT_BASE
if (DEFINED_SEGMENT | DEFINED_SEGMENT_SIZE > 0) & SEGMENT_TYPE = PT_LOAD & OVERLAY_HEADERS
FILE_OFFSET = HEADERS_OFFSET
SEGMENT_BASE = HEADERS_BASE
OVERLAY_HEADERS = 0
end if
store SEGMENT_BASE-DYNAMIC at ELF:p_vaddr+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
store SEGMENT_BASE-DYNAMIC at ELF:p_paddr+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
store FILE_OFFSET at ELF:p_offset+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
if SEGMENT_TYPE = PT_LOAD
RAW_DATA_SIZE = $%% - FILE_OFFSET
SEGMENT_SIZE = $ - SEGMENT_BASE
store RAW_DATA_SIZE at ELF:p_filesz+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
store SEGMENT_SIZE at ELF:p_memsz+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
if DEFINED_SEGMENT | DEFINED_SEGMENT_SIZE > 0
FILE_OFFSET = $%%
align 1000h
SEGMENT_BASE = $ + FILE_OFFSET and 0FFFh
end if
section SEGMENT_BASE
else
if OVERLAY_HEADERS = 0 & ( LOAD_HEADERS | SEGMENT_TYPE = PT_GNU_RELRO ) & ~ SEGMENT_TYPE = PT_GNU_STACK & ~ SEGMENT_TYPE = PT_NOTE
OVERLAY_HEADERS = 1
HEADERS_OFFSET = FILE_OFFSET
HEADERS_BASE = SEGMENT_BASE
end if
FILE_OFFSET = $%
SEGMENT_SIZE = $ - SEGMENT_BASE
store SEGMENT_SIZE at ELF:p_filesz+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
store SEGMENT_SIZE at ELF:p_memsz+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
if OVERLAY_HEADERS = 0
SEGMENT_BASE = DYNAMIC + (SEGMENT_BASE-DYNAMIC) and not 0FFFh + FILE_OFFSET and 0FFFh
else
SEGMENT_BASE = $
end if
if $% > $%%
store 0:byte at $-1
end if
org SEGMENT_BASE
end if
if DEFINED_SEGMENT | DEFINED_SEGMENT_SIZE > 0
SEGMENT_INDEX = SEGMENT_INDEX + 1
end if
end namespace
end macro
macro segment? attributes*
namespace ELF
segment
SEGMENT_TYPE = PT_LOAD
SEGMENT_FLAGS = 0
local seq,list
define seq attributes
while 1
match car cdr, seq
define list car
define seq cdr
else
match any, seq
define list any
end match
break
end match
end while
irpv attribute, list
match =readable?, attribute
SEGMENT_FLAGS = SEGMENT_FLAGS or PF_R
else match =writeable?, attribute
SEGMENT_FLAGS = SEGMENT_FLAGS or PF_W
else match =executable?, attribute
SEGMENT_FLAGS = SEGMENT_FLAGS or PF_X
else match =interpreter?, attribute
SEGMENT_TYPE = PT_INTERP
else match =dynamic?, attribute
SEGMENT_TYPE = PT_DYNAMIC
else match =note?, attribute
SEGMENT_TYPE = PT_NOTE
else match =gnustack?, attribute
SEGMENT_TYPE = PT_GNU_STACK
else match =gnuehframe?, attribute
SEGMENT_TYPE = PT_GNU_EH_FRAME
else match =gnurelro?, attribute
SEGMENT_TYPE = PT_GNU_RELRO
else
err 'unknown attribute "',`attribute,'"'
end match
end irpv
DEFINED_SEGMENT = 1
store SEGMENT_TYPE at ELF:p_type+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
store SEGMENT_FLAGS at ELF:p_flags+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
if SEGMENT_TYPE = PT_LOAD
store 1000h at ELF:p_align+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
else
store 1 at ELF:p_align+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
end if
end namespace
end macro
postpone
purge segment?
segment
namespace ELF
NUMBER_OF_SEGMENTS := SEGMENT_INDEX
end namespace
end postpone

View File

@ -0,0 +1,328 @@
macro format?.MZ?
format binary as 'exe'
include 'format/mz.inc'
include 'p6.inc'
end macro
macro format?.PE? settings
PE.Settings.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_32BIT_MACHINE or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_LOCAL_SYMS_STRIPPED
PE.Settings.DllCharacteristics = 0
local seq
define seq settings:
while 1
match :, seq
break
else match =DLL? more, seq
PE.Settings.Characteristics = PE.Settings.Characteristics or IMAGE_FILE_DLL
redefine seq more
else match =large? more, seq
PE.Settings.Characteristics = PE.Settings.Characteristics or IMAGE_FILE_LARGE_ADDRESS_AWARE
redefine seq more
else match =WDM? more, seq
PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_WDM_DRIVER
redefine seq more
else match =NX? more, seq
PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_NX_COMPAT
redefine seq more
else match =at? base =on? stub :, seq
PE.Settings.ImageBase = base
PE.Settings.Stub = stub
break
else match =at? base :, seq
PE.Settings.ImageBase = base
break
else match =on? stub :, seq
PE.Settings.Stub = stub
break
else
match =GUI? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI
redefine seq more
else match =console? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI
redefine seq more
else match =native? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_NATIVE
PE.Settings.SectionAlignment = 32
PE.Settings.FileAlignment = 32
redefine seq more
else match =EFI? more, seq
PE.Settings.Magic = 0x20B
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION
redefine seq more
else match =EFIboot? more, seq
PE.Settings.Magic = 0x20B
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
redefine seq more
else match =EFIruntime? more, seq
PE.Settings.Magic = 0x20B
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
redefine seq more
else
err 'invalid argument'
break
end match
match V.v more, seq
PE.Settings.MajorSubsystemVersion = V
PE.Settings.MinorSubsystemVersion = v
redefine seq more
end match
end match
end while
if PE.Settings.Characteristics and IMAGE_FILE_DLL
format binary as 'dll'
else
format binary as 'exe'
end if
include 'format/pe.inc'
include 'p6.inc'
use32
end macro
macro format?.PE64? settings
PE.Settings.Magic = 0x20B
PE.Settings.Machine = IMAGE_FILE_MACHINE_AMD64
PE.Settings.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_LARGE_ADDRESS_AWARE or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_LOCAL_SYMS_STRIPPED
PE.Settings.DllCharacteristics = 0
PE.Settings.MajorSubsystemVersion = 5
PE.Settings.MinorSubsystemVersion = 0
local seq
define seq settings:
while 1
match :, seq
break
else match =DLL? more, seq
PE.Settings.Characteristics = PE.Settings.Characteristics or IMAGE_FILE_DLL
redefine seq more
else match =WDM? more, seq
PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_WDM_DRIVER
redefine seq more
else match =NX? more, seq
PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_NX_COMPAT
redefine seq more
else match =at? base =on? stub :, seq
PE.Settings.ImageBase = base
PE.Settings.Stub = stub
break
else match =at? base :, seq
PE.Settings.ImageBase = base
break
else match =on? stub :, seq
PE.Settings.Stub = stub
break
else
match =GUI? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI
redefine seq more
else match =console? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI
redefine seq more
else match =native? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_NATIVE
PE.Settings.SectionAlignment = 32
PE.Settings.FileAlignment = 32
redefine seq more
else match =EFI? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION
redefine seq more
else match =EFIboot? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
redefine seq more
else match =EFIruntime? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
redefine seq more
else
err 'invalid argument'
break
end match
match V.v more, seq
PE.Settings.MajorSubsystemVersion = V
PE.Settings.MinorSubsystemVersion = v
redefine seq more
end match
end match
end while
if PE.Settings.Characteristics and IMAGE_FILE_DLL
format binary as 'dll'
else
format binary as 'exe'
end if
include 'format/pe.inc'
include 'x64.inc'
use64
end macro
macro format?.ELF? variant
match , variant
format binary as 'o'
include 'format/elf32.inc'
include 'p6.inc'
use32
else match =executable? settings, variant:
match brand =at? base:, settings
ELF.Settings.ABI = brand
ELF.Settings.BaseAddress = base
else match =at? base:, settings
ELF.Settings.BaseAddress = base
else match brand:, settings
ELF.Settings.ABI = brand
end match
include 'format/elfexe.inc'
include 'p6.inc'
use32
else match =dynamic? settings, variant:
ELF.Settings.Type = ET_DYN
match brand =at? base:, settings
ELF.Settings.ABI = brand
ELF.Settings.BaseAddress = base
else match =at? base:, settings
ELF.Settings.BaseAddress = base
else match brand:, settings
ELF.Settings.ABI = brand
end match
include 'format/elfexe.inc'
include 'p6.inc'
use32
else
err 'invalid argument'
end match
end macro
macro format?.ELF64? variant
match , variant
format binary as 'o'
include 'format/elf64.inc'
include 'x64.inc'
use64
else match =executable? settings, variant:
ELF.Settings.Class = ELFCLASS64
ELF.Settings.Machine = EM_X86_64
ELF.Settings.BaseAddress = 400000h
match brand =at? base:, settings
ELF.Settings.ABI = brand
ELF.Settings.BaseAddress = base
else match =at? base:, settings
ELF.Settings.BaseAddress = base
else match brand:, settings
ELF.Settings.ABI = brand
end match
include 'format/elfexe.inc'
include 'x64.inc'
use64
else match =dynamic? settings, variant:
ELF.Settings.Class = ELFCLASS64
ELF.Settings.Type = ET_DYN
ELF.Settings.Machine = EM_X86_64
ELF.Settings.BaseAddress = 400000h
match brand =at? base:, settings
ELF.Settings.ABI = brand
ELF.Settings.BaseAddress = base
else match =at? base:, settings
ELF.Settings.BaseAddress = base
else match brand:, settings
ELF.Settings.ABI = brand
end match
include 'format/elfexe.inc'
include 'x64.inc'
use64
else
err 'invalid argument'
end match
end macro
macro format?.ELFx32? variant
match , variant
format binary as 'o'
ELF.Settings.Machine = EM_X86_64
include 'format/elf32.inc'
include 'x64.inc'
use64
else match =executable? settings, variant:
ELF.Settings.Class = ELFCLASS32
ELF.Settings.Machine = EM_X86_64
ELF.Settings.BaseAddress = 400000h
match brand =at? base:, settings
ELF.Settings.ABI = brand
ELF.Settings.BaseAddress = base
else match =at? base:, settings
ELF.Settings.BaseAddress = base
else match brand:, settings
ELF.Settings.ABI = brand
end match
include 'format/elfexe.inc'
include 'x64.inc'
use64
else
err 'invalid argument'
end match
end macro
macro format?.COFF?
format binary as 'obj'
include 'format/coff.inc'
include 'p6.inc'
use32
end macro
macro format?.MS? variant
match =COFF?, variant
format binary as 'obj'
COFF.Settings.Characteristics = IMAGE_FILE_32BIT_MACHINE or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_BYTES_REVERSED_LO
include 'format/coffms.inc'
include 'p6.inc'
use32
else
err 'invalid argument'
end match
end macro
macro format?.MS64? variant
match =COFF?, variant
format binary as 'obj'
COFF.Settings.Machine = IMAGE_FILE_MACHINE_AMD64
COFF.Settings.Characteristics = IMAGE_FILE_32BIT_MACHINE or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_BYTES_REVERSED_LO
include 'format/coffms.inc'
include 'x64.inc'
use64
else
err 'invalid argument'
end match
end macro
macro format?.MachO? variant
match , variant
format binary as 'o'
MachO.Settings.FileType equ MH_OBJECT
include 'format/macho.inc'
include 'p6.inc'
use32
else match =executable?, variant
MachO.Settings.BaseAddress = 0x1000
include 'format/macho.inc'
include 'p6.inc'
use32
else
err 'invalid argument'
end match
end macro
macro format?.MachO64? variant
MachO.Settings.ProcessorType equ CPU_TYPE_X86_64
MachO.Settings.ProcessorSubtype equ CPU_SUBTYPE_X86_64_ALL
match , variant
format binary as 'o'
MachO.Settings.FileType equ MH_OBJECT
include 'format/macho.inc'
include 'x64.inc'
use64
else match =executable?, variant
MachO.Settings.BaseAddress = 0x100000000
include 'format/macho.inc'
include 'x64.inc'
use64
else
err 'invalid argument'
end match
end macro

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,209 @@
MZ::
.signature dw "MZ"
.bytes_in_last_page dw .LENGTH and 1FFh
.number_of_pages dw (.LENGTH-1) shr 9 + 1
.number_of_relocations dw .NUMBER_OF_RELOCATIONS
.number_of_header_paragraphs dw .HEADER_LENGTH shr 4
.minimum_heap dw (.LENGTH+.RESERVED_LENGTH-1) shr 4 - (.LENGTH-1) shr 4
.maximum_heap dw 0FFFFh
.initial_ss dw 0
.initial_sp dw 0
.checksum dw 0
.initial_ip dw 0
.initial_cs dw 0
.relocations_offset dw .relocations
.overlay_number dw 0
.relocations dw .NUMBER_OF_RELOCATIONS dup (?,?)
rb 0Fh - ($%+0Fh) and 0Fh
.HEADER_LENGTH = $
.RELOCATION_INDEX = 0
.ENTRY_DEFINED = 0
.HEAP_DEFINED = 0
.STACK_DEFINED = 0
.STACK_LENGTH = 1000h
org 0
macro entry? definition
local v
if MZ.ENTRY_DEFINED
err 'setting already specified'
else match seg:offs, definition
v = seg
if v relativeto MZ.segment
store v - MZ.segment : word at MZ : MZ.initial_cs
else
err 'incorrect segment'
end if
v = offs
if v >= 0 & v < 10000h
store v : word at MZ : MZ.initial_ip
else
err 'value out of range'
end if
MZ.ENTRY_DEFINED = 1
else
err 'invalid argument'
end match
end macro
macro heap? definition
local v,min
if MZ.HEAP_DEFINED
err 'setting already specified'
else
v = definition
if v >= 0 & v < 10000h
load min : word from MZ : MZ.minimum_heap
v = v + min
if v > 0FFFFh
v = 0FFFFh
end if
store v : word at MZ : MZ.maximum_heap
else
err 'value out of range'
end if
MZ.HEAP_DEFINED = 1
end if
end macro
macro stack? definition
local v
if MZ.STACK_DEFINED
err 'setting already specified'
else match seg:offs, definition
v = seg
if v relativeto MZ.segment
store v - MZ.segment : word at MZ : MZ.initial_ss
else
err 'incorrect segment'
end if
v = offs
if v >= 0 & v < 10000h
store v : word at MZ : MZ.initial_sp
else
err 'value out of range'
end if
MZ.STACK_DEFINED = 1
MZ.STACK_LENGTH = 0
else
MZ.STACK_DEFINED = 1
MZ.STACK_LENGTH = definition
end match
end macro
element MZ.segment
macro segment? definition
rb 0Fh - ($%+0Fh) and 0Fh
match name =use16?, definition
name := MZ.segment + ($%-MZ.HEADER_LENGTH) shr 4
use16
else match name =use32?, definition
name := MZ.segment + ($%-MZ.HEADER_LENGTH) shr 4
use32
else match name, definition
name := MZ.segment + ($%-MZ.HEADER_LENGTH) shr 4
end match
org 0
end macro
calminstruction calminstruction?.initsym? var*, val&
publish var, val
end calminstruction
calminstruction calminstruction?.asm? line&
local name, i
initsym name, name.0
match name.i, name
compute i, i+1
arrange name, name.i
publish name, line
arrange line, =assemble name
assemble line
end calminstruction
iterate <dw,word>, dw,word, dd,dword
calminstruction word? value
compute value, value
check value relativeto MZ.segment
jno plain
local offset
compute offset, $%
emit word, value - MZ.segment
check $% > offset
jno done
compute offset, offset - MZ.HEADER_LENGTH
compute offset, offset and 0FFFFh + (offset and not 0FFFFh) shl 12
asm store offset:4 at MZ : MZ.relocations + MZ.RELOCATION_INDEX shl 2
compute MZ.RELOCATION_INDEX, MZ.RELOCATION_INDEX + 1
done:
exit
plain:
emit word, value
end calminstruction
calminstruction dw? definitions&
local value, n
start:
match value=,definitions, definitions, ()
jyes recognize
match value, definitions
arrange definitions,
recognize:
match n =dup? value, value, ()
jyes duplicate
match ?, value
jyes reserve
call word, value
next:
match , definitions
jno start
take , definitions
take definitions, definitions
jyes next
exit
reserve:
emit word
jump next
duplicate:
match (value), value
stack:
check n
jno next
take definitions, value
arrange value, definitions
compute n, n - 1
jump stack
end calminstruction
calminstruction (label) dw? definitions&
local cmd
arrange cmd, =label label : =word
assemble cmd
arrange cmd, =dw definitions
assemble cmd
end calminstruction
end iterate
calminstruction align? boundary,value:?
compute boundary, (boundary-1)-((0 scaleof $)+boundary-1) mod boundary
arrange value, =db boundary =dup value
assemble value
end calminstruction
postpone
if MZ.STACK_LENGTH
rb 0Fh - ($%+0Fh) and 0Fh
store ($%-MZ.HEADER_LENGTH) shr 4 : word at MZ : MZ.initial_ss
rb MZ.STACK_LENGTH
store MZ.STACK_LENGTH : word at MZ : MZ.initial_sp
end if
MZ.LENGTH = $%%
MZ.RESERVED_LENGTH = $%-$%%
MZ.NUMBER_OF_RELOCATIONS = MZ.RELOCATION_INDEX
end postpone

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
calminstruction element? definition
local name, meta
match =tr? any, definition
jyes skip
arrange definition, =element? definition
assemble definition
skip:
end calminstruction
include '80486.inc'
purge element?
iterate <instr,opcode>, wrmsr,<0Fh,30h>, rdtsc,<0Fh,31h>, rdmsr,<0Fh,32h>, rdpmc,<0Fh,33h>, cpuid,<0Fh,0A2h>, rsm,<0Fh,0AAh>
calminstruction instr?
asm db opcode
end calminstruction
end iterate
calminstruction cmpxchg8b? dest*
call x86.parse_operand@dest, dest
check @dest.type = 'mem'
jyes operand_ok
err 'invalid operand'
exit
operand_ok:
check @dest.size and not 8
jno size_ok
err 'invalid operand size'
size_ok:
xcall x86.store_instruction@dest, <0Fh,0C7h>,(1)
end calminstruction
include '80387.inc'

View File

@ -0,0 +1,62 @@
include 'p5.inc'
iterate <instr,opcode>, sysenter,<0Fh,34h>, sysexit,<0Fh,35h>
calminstruction instr?
asm db opcode
end calminstruction
end iterate
iterate <cond,code>, o,0, no,1, c,2, b,2, nae,2, nc,3, nb,3, ae,3, z,4, e,4, nz,5, ne,5, na,6, be,6, a,7, nbe,7, \
s,8, ns,9, p,0Ah, pe,0Ah, np,0Bh, po,0Bh, l,0Ch, nge,0Ch, nl,0Dh, ge,0Dh, ng,0Eh, le,0Eh, g,0Fh, nle,0Fh
calminstruction cmov#cond? dest*,src*
call x86.parse_operand@dest, dest
call x86.parse_operand@src, src
check @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg')
jyes cmov_rm_reg
err 'invalid combination of operands'
exit
cmov_rm_reg:
check @src.size and not @dest.size
jno cmov_rm_reg_ok
err 'operand sizes do not match'
cmov_rm_reg_ok:
call x86.select_operand_prefix@src, @dest.size
xcall x86.store_instruction@src, <0Fh,40h+code>,@dest.rm
end calminstruction
end iterate
iterate <instr,opcode>, fcmovb,<0DAh,0C0h>, fcmove,<0DAh,0C8h>, fcmovbe,<0DAh,0D0h>, fcmovu,<0DAh,0D8h>, \
fcmovnb,<0DBh,0C0h>, fcmovne,<0DBh,0C8h>, fcmovnbe,<0DBh,0D0h>, fcmovnu,<0DBh,0D8h>
calminstruction instr? dest*,src*
call x87.parse_operand@dest, dest
call x87.parse_operand@src, src
check @dest.type = 'streg' & @dest.rm = 0 & @src.type = 'streg'
jyes ok
err 'invalid operand'
exit
ok:
asm db opcode + @src.rm
end calminstruction
end iterate
iterate <instr,opcode,postbyte>, fucomi,0DBh,5, fucomip,0DFh,5, fcomi,0DBh,6, fcomip,0DFh,6
calminstruction instr? src:st1
call x87.parse_operand@src, src
check @src.type = 'streg'
jyes ok
err 'invalid operand'
exit
ok:
emit 1, opcode
emit 1, 11b shl 6 + postbyte shl 3 + @src.rm
end calminstruction
end iterate

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,209 @@
; Life - fasm example program
; Controls:
; arrow keys - move cursor
; Space - switch cell
; Enter - move to next generation
; Esc - exit program
include '80186.inc'
org 100h
jumps
mov di,screen_data
xor al,al
mov cx,80*50*2
rep stosb
mov ax,3
int 10h ; set text mode
mov ah,1
mov ch,20h
int 10h ; hide cursor
mov ax,1003h
xor bx,bx
int 10h ; enable background intensity
mov ax,1100h
mov bp,DCh_pattern
mov cx,1
mov dx,0DCh
mov bx,1000h
int 10h
mov ax,0B800h
mov es,ax
xor di,di
mov ax,0DCh
mov cx,80*25
rep stosw
redraw_screen:
mov si,[cursor_y]
imul si,80
add si,[cursor_x]
and byte [screen_data+si],8
or byte [screen_data+si],2
mov si,screen_data
xor di,di
mov cx,50
draw_screen:
push cx
mov cx,80
draw_line:
mov ah,[si+80]
lodsb
shl al,4
and ah,0Fh
or al,ah
inc di
stosb
loop draw_line
pop cx
add si,80
loop draw_screen
wait_for_key:
xor ah,ah
int 16h
cmp ah,1
je exit
cmp ah,1Ch
je next_generation
cmp ah,39h
je switch_cell
cmp ah,4Bh
je cursor_left
cmp ah,4Dh
je cursor_right
cmp ah,48h
je cursor_up
cmp ah,50h
je cursor_down
jmp wait_for_key
switch_cell:
mov si,[cursor_y]
imul si,80
add si,[cursor_x]
xor byte [screen_data+si],8
jmp redraw_screen
cursor_left:
cmp [cursor_x],1
jbe wait_for_key
call clear_cursor
dec [cursor_x]
jmp redraw_screen
cursor_right:
cmp [cursor_x],78
jae wait_for_key
call clear_cursor
inc [cursor_x]
jmp redraw_screen
cursor_up:
cmp [cursor_y],1
jbe wait_for_key
call clear_cursor
dec [cursor_y]
jmp redraw_screen
cursor_down:
cmp [cursor_y],48
jae wait_for_key
call clear_cursor
inc [cursor_y]
jmp redraw_screen
next_generation:
call clear_cursor
mov si,screen_data+81
mov di,screen_data+80*50+81
mov cx,48
process_screen:
push cx
mov cx,78
process_line:
xor bl,bl
mov al,[si+1]
and al,1
add bl,al
mov al,[si-1]
and al,1
add bl,al
mov al,[si+80]
and al,1
add bl,al
mov al,[si-80]
and al,1
add bl,al
mov al,[si+80+1]
and al,1
add bl,al
mov al,[si+80-1]
and al,1
add bl,al
mov al,[si-80+1]
and al,1
add bl,al
mov al,[si-80-1]
and al,1
add bl,al
mov al,byte [si]
mov byte [di],al
cmp bl,1
jbe clear_cell
cmp bl,4
jae clear_cell
cmp bl,2
je cell_ok
mov byte [di],0Fh
jmp cell_ok
clear_cell:
mov byte [di],0
cell_ok:
inc si
inc di
loop process_line
pop cx
add si,2
add di,2
loop process_screen
push es
push ds
pop es
mov si,screen_data+80*50
mov di,screen_data
mov cx,80*50
rep movsb
pop es
jmp redraw_screen
exit:
mov ax,3
int 10h
int 20h
clear_cursor:
mov si,[cursor_y]
imul si,80
add si,[cursor_x]
mov al,byte [screen_data+si]
cmp al,2
je empty_cell
mov byte [screen_data+si],0Fh
ret
empty_cell:
mov byte [screen_data+si],0
ret
cursor_x dw 40
cursor_y dw 25
DCh_pattern:
db 8 dup 0
db 8 dup 0FFh
screen_data rb 80*50*2

View File

@ -0,0 +1,9 @@
set include=include
fasmg hello.asm hello.com
fasmg life.asm life.com
fasmg mandel.asm mandel.com
fasmg multiseg.asm multiseg.exe
fasmg usedpmi.asm usedpmi.exe
fasmg win32.asm win32.exe
fasmg win64.asm win64.exe
fasmg win64avx.asm win64avx.exe

View File

@ -0,0 +1,94 @@
; Mandelbrot Set - fasm example program
include '80186.inc'
include '8087.inc'
org 100h
mov ax,13h ; MCGA/VGA
int 10h
push 0A000h
pop es
mov dx,3C8h
xor al,al
out dx,al
inc dl
mov cx,64
vga_palette:
out dx,al
out dx,al
out dx,al
inc al
loop vga_palette
xor di,di
xor dx,dx
finit
fld [y_top]
fstp [y]
screen:
xor bx,bx
fld [x_left]
fstp [x]
row:
finit
fldz
fldz
mov cx,63
iteration:
fld st0
fmul st0,st0
fxch st1
fmul st0,st2
fadd st0,st0
fxch st2
fmul st0,st0
fsubp st1,st0
fxch st1
fadd [y]
fxch st1
fadd [x]
fld st1
fmul st0,st0
fld st1
fmul st0,st0
faddp st1,st0
fsqrt
fistp [i]
cmp [i],2
ja over
loop iteration
over:
mov al,cl
stosb
fld [x]
fadd [x_step]
fstp [x]
inc bx
cmp bx,320
jb row
fld [y]
fsub [y_step]
fstp [y]
inc dx
cmp dx,200
jb screen
xor ah,ah
int 16h
mov ax,3
int 10h
int 20h
x_left dd -2.2
y_top dd 1.25
x_step dd 0.009375
y_step dd 0.0125
x dd ?
y dd ?
i dw ?

View File

@ -0,0 +1,29 @@
include '8086.inc'
include 'format/mz.inc'
entry code:start ; program entry point
stack 100h ; stack size
segment code
start:
mov ax,data
mov ds,ax
mov dx,hello
call extra:write_text
mov ax,4C00h
int 21h
segment data
hello db 'Hello world!',24h
segment extra
write_text:
mov ah,9
int 21h
retf

View File

@ -0,0 +1,99 @@
; This is an example of setting up 32-bit program with flat memory model
; using DPMI. It requires 32-bit DPMI host in order to start.
include '80386.inc'
include 'format/mz.inc'
heap 0 ; no additional memory
segment loader use16
push cs
pop ds
mov ax,1687h
int 2Fh
or ax,ax ; DPMI installed?
jnz error
test bl,1 ; 32-bit programs supported?
jz error
mov word [mode_switch],di
mov word [mode_switch+2],es
mov bx,si ; allocate memory for DPMI data
mov ah,48h
int 21h
jc error
mov es,ax
mov ax,1
call far [mode_switch] ; switch to protected mode
jc error
mov cx,1
xor ax,ax
int 31h ; allocate descriptor for code
mov si,ax
xor ax,ax
int 31h ; allocate descriptor for data
mov di,ax
mov dx,cs
lar cx,dx
shr cx,8
or cx,0C000h
mov bx,si
mov ax,9
int 31h ; set code descriptor access rights
mov dx,ds
lar cx,dx
shr cx,8
or cx,0C000h
mov bx,di
int 31h ; set data descriptor access rights
mov ecx,main
shl ecx,4
mov dx,cx
shr ecx,16
mov ax,7 ; set descriptor base address
int 31h
mov bx,si
int 31h
mov cx,0FFFFh
mov dx,0FFFFh
mov ax,8 ; set segment limit to 4 GB
int 31h
mov bx,di
int 31h
mov ds,di
mov es,di
mov fs,di
mov gs,di
push 0
push si
push dword start
retfd
error:
mov ax,4CFFh
int 21h
mode_switch dd ?
segment main use32
start:
mov esi,hello
.loop:
lodsb
or al,al
jz .done
mov dl,al
mov ah,2
int 21h
jmp .loop
.done:
mov ax,4C00h
int 21h
hello db 'Hello from protected mode!',0Dh,0Ah,0

View File

@ -0,0 +1,46 @@
include 'format/format.inc'
format PE GUI
entry start
section '.text' code readable executable
start:
push 0
push _caption
push _message
push 0
call [MessageBoxA]
push 0
call [ExitProcess]
section '.data' data readable writeable
_caption db 'Win32 assembly program',0
_message db 'Hello World!',0
section '.idata' import data readable writeable
dd 0,0,0,RVA kernel_name,RVA kernel_table
dd 0,0,0,RVA user_name,RVA user_table
dd 0,0,0,0,0
kernel_table:
ExitProcess dd RVA _ExitProcess
dd 0
user_table:
MessageBoxA dd RVA _MessageBoxA
dd 0
kernel_name db 'KERNEL32.DLL',0
user_name db 'USER32.DLL',0
_ExitProcess dw 0
db 'ExitProcess',0
_MessageBoxA dw 0
db 'MessageBoxA',0
section '.reloc' fixups data readable discardable ; needed for Win32s

View File

@ -0,0 +1,45 @@
include 'format/format.inc'
format PE64 GUI
entry start
section '.text' code readable executable
start:
sub rsp,8*5 ; reserve stack for API use and make stack dqword aligned
mov r9d,0
lea r8,[_caption]
lea rdx,[_message]
mov rcx,0
call [MessageBoxA]
mov ecx,eax
call [ExitProcess]
section '.data' data readable writeable
_caption db 'Win64 assembly program',0
_message db 'Hello World!',0
section '.idata' import data readable writeable
dd 0,0,0,RVA kernel_name,RVA kernel_table
dd 0,0,0,RVA user_name,RVA user_table
dd 0,0,0,0,0
kernel_table:
ExitProcess dq RVA _ExitProcess
dq 0
user_table:
MessageBoxA dq RVA _MessageBoxA
dq 0
kernel_name db 'KERNEL32.DLL',0
user_name db 'USER32.DLL',0
_ExitProcess dw 0
db 'ExitProcess',0
_MessageBoxA dw 0
db 'MessageBoxA',0

View File

@ -0,0 +1,114 @@
include 'format/format.inc'
format PE64 NX GUI 5.0
entry start
include 'ext/avx.inc'
section '.data' data readable writeable
_title db 'AVX playground',0
_error db 'AVX instructions are not supported.',0
x dq 3.14159265389
vector_output:
repeat 16, i:0
db 'ymm',`i,': %f,%f,%f,%f',13,10
end repeat
db 0
buffer db 1000h dup ?
section '.text' code readable executable
start:
mov eax,1
cpuid
and ecx,18000000h
cmp ecx,18000000h
jne no_AVX
xor ecx,ecx
xgetbv
and eax,110b
cmp eax,110b
jne no_AVX
vbroadcastsd ymm0, [x]
vsqrtpd ymm1, ymm0
vsubpd ymm2, ymm0, ymm1
vsubpd ymm3, ymm1, ymm2
vaddpd xmm4, xmm2, xmm3
vaddpd ymm5, ymm4, ymm0
vperm2f128 ymm6, ymm4, ymm5, 03h
vshufpd ymm7, ymm6, ymm5, 10010011b
vroundpd ymm8, ymm7, 0011b
vroundpd ymm9, ymm7, 0
sub rsp,418h
repeat 16, i:0
vmovups [rsp+10h+i*32],ymm#i
end repeat
mov r8,[rsp+10h]
mov r9,[rsp+18h]
lea rdx,[vector_output]
lea rcx,[buffer]
call [sprintf]
xor ecx,ecx
lea rdx,[buffer]
lea r8,[_title]
xor r9d,r9d
call [MessageBoxA]
xor ecx,ecx
call [ExitProcess]
no_AVX:
sub rsp,28h
xor ecx,ecx
lea rdx,[_error]
lea r8,[_title]
mov r9d,10h
call [MessageBoxA]
mov ecx,1
call [ExitProcess]
section '.idata' import data readable writeable
dd 0,0,0,RVA kernel_name,RVA kernel_table
dd 0,0,0,RVA user_name,RVA user_table
dd 0,0,0,RVA msvcrt_name,RVA msvcrt_table
dd 0,0,0,0,0
kernel_table:
ExitProcess dq RVA _ExitProcess
dq 0
user_table:
MessageBoxA dq RVA _MessageBoxA
dq 0
msvcrt_table:
sprintf dq RVA _sprintf
dq 0
kernel_name db 'KERNEL32.DLL',0
user_name db 'USER32.DLL',0
msvcrt_name db 'MSVCRT.DLL',0
_ExitProcess dw 0
db 'ExitProcess',0
_MessageBoxA dw 0
db 'MessageBoxA',0
_sprintf dw 0
db 'sprintf',0

BIN
toolchain/fasmg.kl0e/fasmg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,24 @@
flat assembler g
Copyright (c) 2015-2024, Tomasz Grysztar
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,20 @@
The name of flat assembler g (abbreviated to fasmg) is intentionally stylized
with lowercase letters. This is a nod to the history of its precedessor.
The "source" directory contains the complete source code which
can be assembled with either fasm or fasmg except for MacOS version,
which can only be assembled with fasmg.
The executable file for Windows is "fasmg.exe", while "fasmg" and "fasmg.x64"
are for Linux in 32-bit and 64-bit format respectively. The files for MacOS
are at "source/macos/fasmg" and "source/macos/x64/fasmg".
The "source/libc/fasmg.asm" may be used to assemble fasmg as an ELF object
that can then be linked to a 32-bit C library with a third-party linker to
produce an executable native to a particular operating system. A similar
object file in Mach-O format can be assembled from "source/macos/fasmg.o.asm".
When the source code is assembled with fasmg, it depends on the files from
"examples/x86/include" directory that implement the instruction sets and
output formats compatible with flat assembler 1.

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More