add flat assembler toolchain
This commit is contained in:
parent
99e8e4072b
commit
dbfd94ea40
1101
toolchain/fasmg.kl0e/docs/fasmg.txt
Normal file
1101
toolchain/fasmg.kl0e/docs/fasmg.txt
Normal file
File diff suppressed because it is too large
Load Diff
2474
toolchain/fasmg.kl0e/docs/manual.txt
Normal file
2474
toolchain/fasmg.kl0e/docs/manual.txt
Normal file
File diff suppressed because it is too large
Load Diff
861
toolchain/fasmg.kl0e/examples/8051/8051.inc
Normal file
861
toolchain/fasmg.kl0e/examples/8051/8051.inc
Normal 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
|
75
toolchain/fasmg.kl0e/examples/8051/hex.inc
Normal file
75
toolchain/fasmg.kl0e/examples/8051/hex.inc
Normal 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
|
46
toolchain/fasmg.kl0e/examples/8051/invert.asm
Normal file
46
toolchain/fasmg.kl0e/examples/8051/invert.asm
Normal 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
|
1
toolchain/fasmg.kl0e/examples/8051/make.cmd
Normal file
1
toolchain/fasmg.kl0e/examples/8051/make.cmd
Normal file
@ -0,0 +1 @@
|
||||
fasmg invert.asm invert.hex
|
903
toolchain/fasmg.kl0e/examples/avr/avr.inc
Normal file
903
toolchain/fasmg.kl0e/examples/avr/avr.inc
Normal 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
|
54
toolchain/fasmg.kl0e/examples/avr/counter.asm
Normal file
54
toolchain/fasmg.kl0e/examples/avr/counter.asm
Normal 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
|
738
toolchain/fasmg.kl0e/examples/avr/m16def.inc
Normal file
738
toolchain/fasmg.kl0e/examples/avr/m16def.inc
Normal 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
|
||||
|
1
toolchain/fasmg.kl0e/examples/avr/make.cmd
Normal file
1
toolchain/fasmg.kl0e/examples/avr/make.cmd
Normal file
@ -0,0 +1 @@
|
||||
fasmg counter.asm counter.hex
|
134
toolchain/fasmg.kl0e/examples/jvm/Test.asm
Normal file
134
toolchain/fasmg.kl0e/examples/jvm/Test.asm
Normal 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
|
797
toolchain/fasmg.kl0e/examples/jvm/bytecode.inc
Normal file
797
toolchain/fasmg.kl0e/examples/jvm/bytecode.inc
Normal 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
|
254
toolchain/fasmg.kl0e/examples/jvm/jclass.inc
Normal file
254
toolchain/fasmg.kl0e/examples/jvm/jclass.inc
Normal 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'
|
1
toolchain/fasmg.kl0e/examples/jvm/make.cmd
Normal file
1
toolchain/fasmg.kl0e/examples/jvm/make.cmd
Normal file
@ -0,0 +1 @@
|
||||
fasmg Test.asm Test.class
|
14
toolchain/fasmg.kl0e/examples/x86/hello.asm
Normal file
14
toolchain/fasmg.kl0e/examples/x86/hello.asm
Normal 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
|
383
toolchain/fasmg.kl0e/examples/x86/include/80186.inc
Normal file
383
toolchain/fasmg.kl0e/examples/x86/include/80186.inc
Normal 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
|
86
toolchain/fasmg.kl0e/examples/x86/include/80286.inc
Normal file
86
toolchain/fasmg.kl0e/examples/x86/include/80286.inc
Normal 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
|
16
toolchain/fasmg.kl0e/examples/x86/include/80287.inc
Normal file
16
toolchain/fasmg.kl0e/examples/x86/include/80287.inc
Normal 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
|
2712
toolchain/fasmg.kl0e/examples/x86/include/80386.inc
Normal file
2712
toolchain/fasmg.kl0e/examples/x86/include/80386.inc
Normal file
File diff suppressed because it is too large
Load Diff
158
toolchain/fasmg.kl0e/examples/x86/include/80387.inc
Normal file
158
toolchain/fasmg.kl0e/examples/x86/include/80387.inc
Normal 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
|
62
toolchain/fasmg.kl0e/examples/x86/include/80486.inc
Normal file
62
toolchain/fasmg.kl0e/examples/x86/include/80486.inc
Normal 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
|
1605
toolchain/fasmg.kl0e/examples/x86/include/8086.inc
Normal file
1605
toolchain/fasmg.kl0e/examples/x86/include/8086.inc
Normal file
File diff suppressed because it is too large
Load Diff
555
toolchain/fasmg.kl0e/examples/x86/include/8087.inc
Normal file
555
toolchain/fasmg.kl0e/examples/x86/include/8087.inc
Normal 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
|
21
toolchain/fasmg.kl0e/examples/x86/include/ext/adx.inc
Normal file
21
toolchain/fasmg.kl0e/examples/x86/include/ext/adx.inc
Normal 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
|
43
toolchain/fasmg.kl0e/examples/x86/include/ext/aes.inc
Normal file
43
toolchain/fasmg.kl0e/examples/x86/include/ext/aes.inc
Normal 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
|
||||
|
1266
toolchain/fasmg.kl0e/examples/x86/include/ext/avx.inc
Normal file
1266
toolchain/fasmg.kl0e/examples/x86/include/ext/avx.inc
Normal file
File diff suppressed because it is too large
Load Diff
502
toolchain/fasmg.kl0e/examples/x86/include/ext/avx2.inc
Normal file
502
toolchain/fasmg.kl0e/examples/x86/include/ext/avx2.inc
Normal 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
|
10
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512.inc
Normal file
10
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512.inc
Normal 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'
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||
|
494
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512bw.inc
Normal file
494
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512bw.inc
Normal 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
|
29
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512cd.inc
Normal file
29
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512cd.inc
Normal 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
|
||||
|
463
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512dq.inc
Normal file
463
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512dq.inc
Normal 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
|
39
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512er.inc
Normal file
39
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512er.inc
Normal 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
|
2660
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512f.inc
Normal file
2660
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512f.inc
Normal file
File diff suppressed because it is too large
Load Diff
62
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512pf.inc
Normal file
62
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512pf.inc
Normal 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
|
@ -0,0 +1,8 @@
|
||||
|
||||
if ~ defined AVX_512
|
||||
|
||||
include 'avx512f.inc'
|
||||
|
||||
end if
|
||||
|
||||
AVX512VL = 1
|
97
toolchain/fasmg.kl0e/examples/x86/include/ext/bmi1.inc
Normal file
97
toolchain/fasmg.kl0e/examples/x86/include/ext/bmi1.inc
Normal 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
|
106
toolchain/fasmg.kl0e/examples/x86/include/ext/bmi2.inc
Normal file
106
toolchain/fasmg.kl0e/examples/x86/include/ext/bmi2.inc
Normal 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
|
@ -0,0 +1,8 @@
|
||||
|
||||
iterate <instr,modrm>, endbr32,0FBh, endbr64,0FAh
|
||||
|
||||
macro instr?
|
||||
db 0F3h,0Fh,1Eh,modrm
|
||||
end macro
|
||||
|
||||
end iterate
|
106
toolchain/fasmg.kl0e/examples/x86/include/ext/cet_ss.inc
Normal file
106
toolchain/fasmg.kl0e/examples/x86/include/ext/cet_ss.inc
Normal 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
|
29
toolchain/fasmg.kl0e/examples/x86/include/ext/f16c.inc
Normal file
29
toolchain/fasmg.kl0e/examples/x86/include/ext/f16c.inc
Normal 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
|
30
toolchain/fasmg.kl0e/examples/x86/include/ext/fma.inc
Normal file
30
toolchain/fasmg.kl0e/examples/x86/include/ext/fma.inc
Normal 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
|
24
toolchain/fasmg.kl0e/examples/x86/include/ext/fsgsbase.inc
Normal file
24
toolchain/fasmg.kl0e/examples/x86/include/ext/fsgsbase.inc
Normal 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
|
||||
|
53
toolchain/fasmg.kl0e/examples/x86/include/ext/gfni.inc
Normal file
53
toolchain/fasmg.kl0e/examples/x86/include/ext/gfni.inc
Normal 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
|
||||
|
16
toolchain/fasmg.kl0e/examples/x86/include/ext/hle.inc
Normal file
16
toolchain/fasmg.kl0e/examples/x86/include/ext/hle.inc
Normal 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
|
||||
|
||||
|
15
toolchain/fasmg.kl0e/examples/x86/include/ext/invpcid.inc
Normal file
15
toolchain/fasmg.kl0e/examples/x86/include/ext/invpcid.inc
Normal 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
|
||||
|
149
toolchain/fasmg.kl0e/examples/x86/include/ext/mmx.inc
Normal file
149
toolchain/fasmg.kl0e/examples/x86/include/ext/mmx.inc
Normal 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
|
23
toolchain/fasmg.kl0e/examples/x86/include/ext/movdir64b.inc
Normal file
23
toolchain/fasmg.kl0e/examples/x86/include/ext/movdir64b.inc
Normal 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
|
||||
|
19
toolchain/fasmg.kl0e/examples/x86/include/ext/movdiri.inc
Normal file
19
toolchain/fasmg.kl0e/examples/x86/include/ext/movdiri.inc
Normal 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
|
||||
|
196
toolchain/fasmg.kl0e/examples/x86/include/ext/mpx.inc
Normal file
196
toolchain/fasmg.kl0e/examples/x86/include/ext/mpx.inc
Normal 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
|
14
toolchain/fasmg.kl0e/examples/x86/include/ext/pclmulqdq.inc
Normal file
14
toolchain/fasmg.kl0e/examples/x86/include/ext/pclmulqdq.inc
Normal 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
|
18
toolchain/fasmg.kl0e/examples/x86/include/ext/ptwrite.inc
Normal file
18
toolchain/fasmg.kl0e/examples/x86/include/ext/ptwrite.inc
Normal 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
|
10
toolchain/fasmg.kl0e/examples/x86/include/ext/rdrand.inc
Normal file
10
toolchain/fasmg.kl0e/examples/x86/include/ext/rdrand.inc
Normal 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
|
10
toolchain/fasmg.kl0e/examples/x86/include/ext/rdseed.inc
Normal file
10
toolchain/fasmg.kl0e/examples/x86/include/ext/rdseed.inc
Normal 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
|
4
toolchain/fasmg.kl0e/examples/x86/include/ext/rdtscp.inc
Normal file
4
toolchain/fasmg.kl0e/examples/x86/include/ext/rdtscp.inc
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
macro rdtscp?
|
||||
db 0Fh,1,0F9h
|
||||
end macro
|
39
toolchain/fasmg.kl0e/examples/x86/include/ext/rtm.inc
Normal file
39
toolchain/fasmg.kl0e/examples/x86/include/ext/rtm.inc
Normal 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
|
4
toolchain/fasmg.kl0e/examples/x86/include/ext/smx.inc
Normal file
4
toolchain/fasmg.kl0e/examples/x86/include/ext/smx.inc
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
macro getsec?
|
||||
db 0Fh,37h
|
||||
end macro
|
433
toolchain/fasmg.kl0e/examples/x86/include/ext/sse.inc
Normal file
433
toolchain/fasmg.kl0e/examples/x86/include/ext/sse.inc
Normal 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
|
603
toolchain/fasmg.kl0e/examples/x86/include/ext/sse2.inc
Normal file
603
toolchain/fasmg.kl0e/examples/x86/include/ext/sse2.inc
Normal 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
|
72
toolchain/fasmg.kl0e/examples/x86/include/ext/sse3.inc
Normal file
72
toolchain/fasmg.kl0e/examples/x86/include/ext/sse3.inc
Normal 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
|
204
toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.1.inc
Normal file
204
toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.1.inc
Normal 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
|
54
toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.2.inc
Normal file
54
toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.2.inc
Normal 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
|
26
toolchain/fasmg.kl0e/examples/x86/include/ext/ssse3.inc
Normal file
26
toolchain/fasmg.kl0e/examples/x86/include/ext/ssse3.inc
Normal 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
|
37
toolchain/fasmg.kl0e/examples/x86/include/ext/vaes.inc
Normal file
37
toolchain/fasmg.kl0e/examples/x86/include/ext/vaes.inc
Normal 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
|
65
toolchain/fasmg.kl0e/examples/x86/include/ext/vmx.inc
Normal file
65
toolchain/fasmg.kl0e/examples/x86/include/ext/vmx.inc
Normal 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
|
32
toolchain/fasmg.kl0e/examples/x86/include/ext/vpclmulqdq.inc
Normal file
32
toolchain/fasmg.kl0e/examples/x86/include/ext/vpclmulqdq.inc
Normal 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
|
35
toolchain/fasmg.kl0e/examples/x86/include/ext/xsave.inc
Normal file
35
toolchain/fasmg.kl0e/examples/x86/include/ext/xsave.inc
Normal 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
|
470
toolchain/fasmg.kl0e/examples/x86/include/format/coff.inc
Normal file
470
toolchain/fasmg.kl0e/examples/x86/include/format/coff.inc
Normal 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
|
754
toolchain/fasmg.kl0e/examples/x86/include/format/coffms.inc
Normal file
754
toolchain/fasmg.kl0e/examples/x86/include/format/coffms.inc
Normal 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
|
640
toolchain/fasmg.kl0e/examples/x86/include/format/elf32.inc
Normal file
640
toolchain/fasmg.kl0e/examples/x86/include/format/elf32.inc
Normal 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
|
652
toolchain/fasmg.kl0e/examples/x86/include/format/elf64.inc
Normal file
652
toolchain/fasmg.kl0e/examples/x86/include/format/elf64.inc
Normal 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
|
326
toolchain/fasmg.kl0e/examples/x86/include/format/elfexe.inc
Normal file
326
toolchain/fasmg.kl0e/examples/x86/include/format/elfexe.inc
Normal 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
|
328
toolchain/fasmg.kl0e/examples/x86/include/format/format.inc
Normal file
328
toolchain/fasmg.kl0e/examples/x86/include/format/format.inc
Normal 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
|
||||
|
1186
toolchain/fasmg.kl0e/examples/x86/include/format/macho.inc
Normal file
1186
toolchain/fasmg.kl0e/examples/x86/include/format/macho.inc
Normal file
File diff suppressed because it is too large
Load Diff
209
toolchain/fasmg.kl0e/examples/x86/include/format/mz.inc
Normal file
209
toolchain/fasmg.kl0e/examples/x86/include/format/mz.inc
Normal 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
|
1064
toolchain/fasmg.kl0e/examples/x86/include/format/pe.inc
Normal file
1064
toolchain/fasmg.kl0e/examples/x86/include/format/pe.inc
Normal file
File diff suppressed because it is too large
Load Diff
37
toolchain/fasmg.kl0e/examples/x86/include/p5.inc
Normal file
37
toolchain/fasmg.kl0e/examples/x86/include/p5.inc
Normal 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'
|
62
toolchain/fasmg.kl0e/examples/x86/include/p6.inc
Normal file
62
toolchain/fasmg.kl0e/examples/x86/include/p6.inc
Normal 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
|
3476
toolchain/fasmg.kl0e/examples/x86/include/x64.inc
Normal file
3476
toolchain/fasmg.kl0e/examples/x86/include/x64.inc
Normal file
File diff suppressed because it is too large
Load Diff
209
toolchain/fasmg.kl0e/examples/x86/life.asm
Normal file
209
toolchain/fasmg.kl0e/examples/x86/life.asm
Normal 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
|
9
toolchain/fasmg.kl0e/examples/x86/make.cmd
Normal file
9
toolchain/fasmg.kl0e/examples/x86/make.cmd
Normal 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
|
94
toolchain/fasmg.kl0e/examples/x86/mandel.asm
Normal file
94
toolchain/fasmg.kl0e/examples/x86/mandel.asm
Normal 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 ?
|
29
toolchain/fasmg.kl0e/examples/x86/multiseg.asm
Normal file
29
toolchain/fasmg.kl0e/examples/x86/multiseg.asm
Normal 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
|
99
toolchain/fasmg.kl0e/examples/x86/usedpmi.asm
Normal file
99
toolchain/fasmg.kl0e/examples/x86/usedpmi.asm
Normal 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
|
46
toolchain/fasmg.kl0e/examples/x86/win32.asm
Normal file
46
toolchain/fasmg.kl0e/examples/x86/win32.asm
Normal 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
|
45
toolchain/fasmg.kl0e/examples/x86/win64.asm
Normal file
45
toolchain/fasmg.kl0e/examples/x86/win64.asm
Normal 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
|
114
toolchain/fasmg.kl0e/examples/x86/win64avx.asm
Normal file
114
toolchain/fasmg.kl0e/examples/x86/win64avx.asm
Normal 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
BIN
toolchain/fasmg.kl0e/fasmg
Normal file
Binary file not shown.
BIN
toolchain/fasmg.kl0e/fasmg.exe
Normal file
BIN
toolchain/fasmg.kl0e/fasmg.exe
Normal file
Binary file not shown.
BIN
toolchain/fasmg.kl0e/fasmg.x64
Normal file
BIN
toolchain/fasmg.kl0e/fasmg.x64
Normal file
Binary file not shown.
24
toolchain/fasmg.kl0e/license.txt
Normal file
24
toolchain/fasmg.kl0e/license.txt
Normal 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.
|
20
toolchain/fasmg.kl0e/readme.txt
Normal file
20
toolchain/fasmg.kl0e/readme.txt
Normal 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.
|
3383
toolchain/fasmg.kl0e/source/assembler.inc
Normal file
3383
toolchain/fasmg.kl0e/source/assembler.inc
Normal file
File diff suppressed because it is too large
Load Diff
3293
toolchain/fasmg.kl0e/source/calm.inc
Normal file
3293
toolchain/fasmg.kl0e/source/calm.inc
Normal file
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
Loading…
x
Reference in New Issue
Block a user