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…
Reference in New Issue
Block a user