aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrahflow <drahflow@gmx.de>2013-12-31 00:54:59 +0100
committerDrahflow <drahflow@gmx.de>2013-12-31 00:54:59 +0100
commit643d6dca1e6026ebf8cfa551ae3e95cc69003c47 (patch)
treedf79289945ee98efee9be9ca201eb1a6fda8c840
parent9699795a62506f69cb83fa35cb58e7641690eb5f (diff)
Less memory usage still
Also, sys .opt now needs less luck to execute correctly.
-rw-r--r--compiler/elymasAsm.ey1249
-rw-r--r--compiler/elymasGlobal.ey32
-rw-r--r--compiler/elymasLexer.ey13
-rw-r--r--compiler/elymasTokenize.ey11
-rw-r--r--compiler/standard.ey8
-rw-r--r--compiler/standardClient.ey21
-rw-r--r--elymas/lib/sys/opt.ey54
-rw-r--r--elymas/lib/sys/so.ey7
-rw-r--r--elymas/loaded.ey2
-rw-r--r--elymas/memdump.ey2
-rw-r--r--elymas/optimized.ey1
-rw-r--r--elymas/shared.ey2
12 files changed, 110 insertions, 1292 deletions
diff --git a/compiler/elymasAsm.ey b/compiler/elymasAsm.ey
index 3f166b1..1fcdd35 100644
--- a/compiler/elymasAsm.ey
+++ b/compiler/elymasAsm.ey
@@ -11,1254 +11,7 @@
-20*10* 16 mul add
} "%" defq
- # registers
- < [ /rax /rcx /rdx /rbx /rsp /rbp /rsi /rdi /r8 /r9 /r10 /r11 /r12 /r13 /r14 /r15 ] { 1 -01 defv }' each > ==:bit64table
- { bit64table -01 . -- } /bit64assert deff
-
- < [ /eax /ecx /edx /ebx /esp /ebp /esi /edi /r8d /r9d /r10d /r11d /r12d /r13d /r14d /r15d ] { 1 -01 defv }' each > ==:bit32table
- { bit32table -01 . -- } /bit32assert deff
-
- < [ /ax /cx /dx /bx /sp /bp /si /di /r8w /r9w /r10w /r11w /r12w /r13w /r14w /r15w ] { 1 -01 defv }' each > ==:bit16table
- { bit16table -01 . -- } /bit16assert deff
-
- < [ /al /cl /dl /bl /spl /ah /bpl /ch /sil /dh /dil /bh /r8b /r9b /r10b /r11b /r12b /r13b /r14b /r15b ] { 1 -01 defv }' each > ==:bit8table
- { bit8table -01 . -- } /bit8assert deff
-
- <
- [ /zero /al /ax /eax /rax /none ] { 0 -01 defv }' each
- [ /one /cl /cx /ecx /rcx ] { 1 -01 defv }' each
- [ /two /dl /dx /edx /rdx ] { 2 -01 defv }' each
- [ /three /bl /bx /ebx /rbx ] { 3 -01 defv }' each
- [ /four /sib /spl /ah /sp /esp /rsp ] { 4 -01 defv }' each
- [ /five /bpl /bp /ebp /rbp ] { 5 -01 defv }' each
- [ /six /sil /si /esi /rsi ] { 6 -01 defv }' each
- [ /seven /dil /di /edi /rdi ] { 7 -01 defv }' each
- [ /r8b /r8w /r8d /r8 ] { 8 -01 defv }' each
- [ /r9b /r9w /r9d /r9 ] { 9 -01 defv }' each
- [ /r10b /r10w /r10d /r10 ] { 10 -01 defv }' each
- [ /r11b /r11w /r11d /r11 ] { 11 -01 defv }' each
- [ /r12b /r12w /r12d /r12 ] { 12 -01 defv }' each
- [ /r13b /r13w /r13d /r13 ] { 13 -01 defv }' each
- [ /r14b /r14w /r14d /r14 ] { 14 -01 defv }' each
- [ /r15b /r15w /r15d /r15 ] { 15 -01 defv }' each
- > ==:regnoTable
-
- { regnoTable -01 . } /regno deff
-
- <
- [ /al /cl /dl /bl ] { 0 -01 defv }' each
- [ /spl /bpl /sil /dil ] { 1 -01 defv }' each
- [ /r8b /r9b /r10b /r11b /r12b /r13b /r14b /r15b ] { 1 -01 defv }' each
- > ==:rexreqbyteTable
-
- { rexreqbyteTable -01 . } /rexreqbyte deff
-
- # encoding a REX prefix
- { # ==b ==x ==r ==w
- %40
- -01 regno %08 band 0 gt %01 mul add
- -01 regno %08 band 0 gt %02 mul add
- -01 regno %08 band 0 gt %04 mul add
- -01 0 gt %08 mul add
- } /rex deff
-
- { ==mem ==reg
- mem [ /spl /sp /esp /rsp /bpl /bp /ebp /rbp ] streq any {
- "modrm00 not possible on rsp / rbp and their partial registers" die
- } rep
-
- %00
- mem regno %07 band add
- reg regno 8 mul %38 band add
- } /modrm00 deff
-
- { ==mem ==reg
- mem [ /spl /sp /esp /rsp ] streq any {
- # actually encode sib with rsp index register (to get it ignored)
- %40
- /sib regno %07 band add
- reg regno 8 mul %38 band add
-
- # sib-byte
- %00 # index = 1 (ignored anyway)
- %38 /rsp regno 8 mul band add # (ignored)
- %07 mem regno band add
- } {
- %40
- mem regno %07 band add
- reg regno 8 mul %38 band add
- } ? *
- } /modrm01 deff
-
- { ==mem ==reg
- mem [ /spl /sp /esp /rsp ] streq any {
- # actually encode sib with rsp index register (to get it ignored)
- %80
- /sib regno %07 band add
- reg regno 8 mul %38 band add
-
- # sib-byte
- %00 # index = 1 (ignored anyway)
- %38 /rsp regno 8 mul band add # (ignored)
- %07 mem regno band add
- } {
- %80
- mem regno %07 band add
- reg regno 8 mul %38 band add
- } ? *
- } /modrm10 deff
-
- { ==mem ==reg
- %C0
- mem regno %07 band add
- reg regno 8 mul %38 band add
- } /modrm11 deff
-
- { ==base ==idx ==scale
- idx [ /spl /sp /esp /rsp ] streq any { "sib cannot encode rsp as index" die } rep
- base [ /bpl /bp /ebp /rbp ] streq any { "sib cannot encode rbp as base" die } rep
- scale _ 0 gt not { "invalid scale chosen for sib" die } rep
- 8 le not { "invalid scale chosen for sib" die } rep
-
- scale [ 1 %00 %40 1 %80 1 1 1 %C0 ] *
- _ 1 eq { "invalid scale chosen for sib" die } rep
- %C0 band
- %38 idx regno 8 mul band add
- %07 base regno band add
- } /sib deff
-
- { 8 { _ 256 mod -01 256 div } rep -- } /imm64 deff # div / mod unsigned
- { _ 0 lt { 4294967296 add } rep 4294967295 band 4 { _ 256 mod -01 256 div } rep -- } /imm32 deff
- { _ 0 lt { 65536 add } rep 65535 band 2 { _ 256 mod -01 256 div } rep -- } /imm16 deff
- { _ 0 lt { 256 add } rep 255 band } /imm8 deff
-
- { %66 } /width16 deff
-
- # label handling
- < { defv }' /put deff > ==labels
- [ ] ==labelHoles
-
- { ==l
- ] _ len l labels .put [ -011 len dearray
- } /label deff
-
- { ==l
- ] _ len ==offset
- labelHoles [ {
- labels l . offset 1 add sub
- _ 128 lt not { "8 bit relative label out of range: " l cat die } rep
- _ 128 neg ge not { "8 bit relative label out of range: " l cat die } rep
- imm8 offset -102 =[] } ] cat =labelHoles
- [ -011 len dearray %00
- } /labelRel8 deff
-
- { ==l
- ] _ len ==offset
- labelHoles [ {
- labels l . offset 2 add sub
- _ 32768 lt not { "16 bit relative label out of range: " l cat die } rep
- _ 32768 neg ge not { "16 bit relative label out of range: " l cat die } rep
- imm16 offset [ 0 1 ] add 2 dearray -204314 =[] =[] } ] cat =labelHoles
- [ -011 len dearray %00 %00
- } /labelRel16 deff
-
- { ==l
- ] _ len ==offset
- labelHoles [ {
- labels l . offset 4 add sub
- _ 2147483648 lt not { "32 bit relative label out of range: " l cat die } rep
- _ 2147483648 neg ge not { "32 bit relative label out of range" l cat die } rep
- imm32 offset [ 0 1 2 3 ] add 4 dearray -408518628738 =[] =[] =[] =[] } ] cat =labelHoles
- [ -011 len dearray %00 %00 %00 %00
- } /labelRel32 deff
-
- { ==opcodes
- labelHoles { opcodes -01 * } each
-
- < { defv }' /put deff > =labels
- [ ] =labelHoles
-
- opcodes
- } /labelResolve deff
-
- { < ==opcode ==name
- { ==offset
- offset 128 neg ge not { "Rel8 offset below -128" die } rep
- offset 128 lt not { "Rel8 offset above 127" die } rep
-
- opcode
- offset imm8
- } name "Rel8" cat
-
- { ==lbl
-
- opcode
- lbl labelRel8
- } name "Lbl8" cat
- > -- 2 |deff rep
- }' /defJmpRel8 deff
-
- { "opcode only exists on AMD cpus (and has 'interesting' semantics even there)" die } /defJmpRel16 deff
-
- { < ==opcode ==name
- { ==offset
- offset 2147483648 neg ge not { "Rel32 offset below -2147483648" die } rep
- offset 2147483648 lt not { "Rel32 offset above 2147483647" die } rep
-
- %0F
- opcode
- offset imm32
- } name "Rel32" cat
-
- { ==lbl
-
- %0F
- opcode
- lbl labelRel32
- } name "Lbl32" cat
- > -- 2 |deff rep
- }' /defJmpRel32 deff
-
- # generalized arithmethic 8086 instructions
- # { cat _ { "executing " -01 cat dump }_ -102 ; -01 deff }' /defOp deff # debugging version
- { cat deff }' /defOp deff
- <
- # base register only
- { < _ bit64assert ==base /none ==idx { ==r
- r base modrm00
- } /encode deff >
- } ==Mem
- # base register plus 8 bit displacement
- { < _ bit64assert ==base /none ==idx _ 128 lt not { "Disp8 too large" die } rep ==disp { ==r
- r base modrm01
- disp imm8
- } /encode deff >
- } ==MemDisp8
- # base register plus 32 bit displacement
- { < _ bit64assert ==base /none ==idx ==disp { ==r
- r base modrm10
- disp imm32
- } /encode deff >
- } ==MemDisp32
- # base and index register
- { < _ bit64assert ==base _ bit64assert ==idx { ==r
- r /sib modrm00
- 1 idx base sib
- } /encode deff >
- } ==MemIndex
- # base and scaled index register
- { < _ bit64assert ==base _ bit64assert ==idx ==scale { ==r
- r /sib modrm00
- scale idx base sib
- } /encode deff >
- } ==MemIndexScale
- # base and scaled index register plus 8 bit displacement
- { < _ bit64assert ==base _ bit64assert ==idx ==scale _ 128 lt not { "Disp8 too large" die } rep ==disp { ==r
- r /sib modrm01
- scale idx base sib
- disp imm8
- } /encode deff >
- } ==MemIndexScaleDisp8
- # base and scaled index register plus 8 bit displacement
- { < _ bit64assert ==base _ bit64assert ==idx ==scale ==disp { ==r
- r /sib modrm10
- scale idx base sib
- disp imm32
- } /encode deff >
- } ==MemIndexScaleDisp32
- > ==memoryAddressingVariants
-
- { ==opcode ==mnemonic
- { ==dst ==src
- src bit8assert
- dst bit8assert
-
- src regno %07 gt dst regno %07 gt src rexreqbyte dst rexreqbyte or or or { 0 src /none dst rex } rep
- opcode
- src dst modrm11
- } mnemonic /bRegReg defOp
-
- memoryAddressingVariants keys { ==variant memoryAddressingVariants variant . =*parse
- { parse ==mem ==reg
- reg bit8assert
-
- reg regno %07 gt reg rexreqbyte mem .base regno %07 gt mem .idx regno %07 gt or or or
- { 0 reg mem .idx mem .base rex } rep
- opcode
- reg mem .encode
- } mnemonic /bReg variant cat defOp
-
- { ==reg parse ==mem
- reg bit8assert
-
- reg regno %07 gt reg rexreqbyte mem .base regno %07 gt mem .idx regno %07 gt or or or
- { 0 reg mem .idx mem .base rex } rep
- opcode %02 add
- reg mem .encode
- } mnemonic /b variant cat /Reg cat defOp
- } each
- } /defAsmAddb deff
-
- { ==opcode ==mnemonic
- { ==dst ==src
- dst bit32assert
- src bit32assert
-
- dst regno %07 gt src regno %07 gt or
- { 0 src /none dst rex } rep
- opcode
- src dst modrm11
- } mnemonic /lRegReg defOp
-
- memoryAddressingVariants keys { ==variant memoryAddressingVariants variant . =*parse
- { parse ==mem ==reg
- reg bit32assert
-
- reg regno %07 gt mem .base regno %07 gt mem .idx regno %07 gt or or
- { 0 reg mem .idx mem .base rex } rep
- opcode
- reg mem .encode
- } mnemonic /lReg variant cat defOp
-
- { ==reg parse ==mem
- reg bit32assert
-
- reg regno %07 gt mem .base regno %07 gt mem .idx regno %07 gt or or
- { 0 reg mem .idx mem .base rex } rep
- opcode %02 add
- reg mem .encode
- } mnemonic /l variant cat /Reg cat defOp
- } each
- } /defAsmAddl deff
-
- { ==opcode ==mnemonic
- { ==dst ==src
- dst bit64assert
- src bit64assert
-
- 1 src /none dst rex
- opcode
- src dst modrm11
- } mnemonic /qRegReg defOp
-
- memoryAddressingVariants keys { ==variant memoryAddressingVariants variant . =*parse
- { parse ==mem ==reg
- reg bit64assert
-
- 1 reg mem .idx mem .base rex
- opcode
- reg mem .encode
- } mnemonic /qReg variant cat defOp
-
- { ==reg parse ==mem
- reg bit64assert
-
- 1 reg mem .idx mem .base rex
- opcode %02 add
- reg mem .encode
- } mnemonic /q variant cat /Reg cat defOp
- } each
- } /defAsmAddq deff
-
- { ==modrmOpcode ==mnemonic
- { ==reg =i
- reg bit8assert
- i 256 lt not { "Imm8 too large" die } rep
-
- reg regno %07 gt reg rexreqbyte or { 0 /none /none reg rex } rep
- %80
- modrmOpcode reg modrm11
- i imm8
- } mnemonic /bImmReg defOp
-
- { ==reg ==i
- reg bit64assert
- i 256 lt not { "Imm8 too large" die } rep
-
- 1 /none /none reg rex
- %83
- modrmOpcode reg modrm11
- i imm8
- } mnemonic /qImm8Reg defOp
-
- memoryAddressingVariants keys { ==variant memoryAddressingVariants variant . =*parse
- { parse ==mem ==i
- i 256 lt not { "Imm8 too large" die } rep
-
- mem .base regno %07 gt mem .idx regno %07 gt or
- { 0 /none mem .idx mem .base rex } rep
- %80
- modrmOpcode mem .encode
- i imm8
- } mnemonic /bImm variant cat defOp
-
- { parse ==mem ==i
- i 65536 lt not { "Imm16 too large" die } rep
-
- width16
- mem .base regno %07 gt mem .idx regno %07 gt or
- { 0 /none mem .idx mem .base rex } rep
- %81
- modrmOpcode mem .encode
- i imm16
- } mnemonic /wImm variant cat defOp
-
- { parse ==mem ==i
- i 256 lt not { "Imm8 too large" die } rep
-
- 1 /none mem .idx mem .base rex
- %83
- modrmOpcode mem .encode
- i imm8
- } mnemonic /qImm8 variant cat defOp
- } each
- } /defAsmAddImm deff
-
- # instructions
- { ==reg ==mem
- reg bit32assert
- mem bit64assert
-
- reg regno %07 gt mem regno %07 gt or { 0 reg /none mem rex } rep
- %03
- reg mem modrm00
- } /addlMemReg deff
-
- { ==opcode2 ==opcode1 ==mnemonic
- { ==reg2 ==reg1
- reg2 bit64assert
- reg1 bit64assert
-
- 1 reg1 /none reg2 rex
- opcode1
- opcode2
- reg1 reg2 modrm11
- } mnemonic /qRegReg defOp
-
- memoryAddressingVariants keys { ==variant memoryAddressingVariants variant . =*parse
- { parse ==mem ==reg
- reg bit64assert
-
- 1 reg mem .idx mem .base rex
- opcode1
- opcode2
- reg mem .encode
- } mnemonic /qReg variant cat defOp
- } each
- } /defAsmBtq deff
-
- { ==opcode2 ==opcode1 ==mnemonic
- { ==reg1 ==reg2
- reg2 bit64assert
- reg1 bit64assert
-
- 1 reg1 /none reg2 rex
- opcode1
- opcode2
- reg1 reg2 modrm11
- } mnemonic /qRegReg defOp
-
- memoryAddressingVariants keys { ==variant memoryAddressingVariants variant . =*parse
- { ==reg parse ==mem
- reg bit64assert
-
- 1 reg mem .idx mem .base rex
- opcode1
- opcode2
- reg mem .encode
- } mnemonic /qReg variant cat defOp
- } each
- } /defAsmBsfq deff
-
- { ==modrmOpcode ==opcode2 ==opcode1 ==mnemonic
- { ==reg ==i
- reg bit64assert
-
- 1 /none /none reg rex
- opcode1
- opcode2
- modrmOpcode reg modrm11
- i imm8
- } mnemonic /qImm8Reg defOp
-
- memoryAddressingVariants keys { ==variant memoryAddressingVariants variant . =*parse
- { parse ==mem ==imm
- 1 /none mem .idx mem .base rex
- opcode1
- opcode2
- modrmOpcode mem .encode
- imm imm8
- } mnemonic /qImm8 variant cat defOp
- } each
- } /defAsmBtqImm deff
-
- /adc %11 defAsmAddq
- /adc /two defAsmAddImm
-
- /add %01 defAsmAddq
- /add /zero defAsmAddImm
-
- /and %20 defAsmAddb
- /and %21 defAsmAddq
- /and /four defAsmAddImm
-
- /bt %0F %A3 defAsmBtq
- /bt %0F %BA /four defAsmBtqImm
-
- /btr %0F %B3 defAsmBtq
- /btr %0F %BA /six defAsmBtqImm
-
- /bts %0F %AB defAsmBtq
- /bts %0F %BA /five defAsmBtqImm
-
- /bsf %0F %BC defAsmBsfq
-
- { ==off
- %E8
- off imm32
- } /callqRel32 deff
-
- { ==lbl
- %E8
- lbl labelRel32
- } /callqLbl32 deff
-
- { ==reg
- reg bit64assert
-
- reg regno %07 gt { 1 /none /none reg rex } rep
- %FF
- /two reg modrm11
- } /callqReg deff
-
- memoryAddressingVariants keys { ==variant memoryAddressingVariants variant . =*parse
- { parse ==mem
- mem .base regno %07 gt mem .idx regno %07 gt or
- { 0 /none mem .idx mem .base rex } rep
- %FF
- /two mem .encode
- } /callq variant defOp
- } each
-
- {
- %FC
- } /cld deff
-
- { ==dst ==src
- src bit64assert
- dst bit64assert
-
- 1 dst /none src rex
- %0F
- %47
- dst src modrm11
- } /cmovaqRegReg deff
-
- { ==dst ==src
- src bit64assert
- dst bit64assert
-
- 1 dst /none src rex
- %0F
- %46
- dst src modrm11
- } /cmovnaqRegReg deff
-
- { ==dst ==src
- src bit64assert
- dst bit64assert
-
- 1 dst /none src rex
- %0F
- %43
- dst src modrm11
- } /cmovaeqRegReg deff
-
- { ==dst ==src
- src bit64assert
- dst bit64assert
-
- 1 dst /none src rex
- %0F
- %42
- dst src modrm11
- } /cmovnaeqRegReg deff
-
- { ==dst ==src
- src bit64assert
- dst bit64assert
-
- 1 dst /none src rex
- %0F
- %42
- dst src modrm11
- } /cmovcqRegReg deff
-
- { ==dst ==src
- src bit64assert
- dst bit64assert
-
- 1 dst /none src rex
- %0F
- %4F
- dst src modrm11
- } /cmovgqRegReg deff
-
- { ==reg ==mem
- mem bit64assert
- reg bit64assert
-
- 1 reg /none mem rex
- %0F
- %43
- reg mem modrm00
- } /cmovncqMemReg deff
-
- { ==reg ==mem ==disp
- disp 128 lt not { "Disp8 out of range" die } rep
- mem bit64assert
- reg bit64assert
-
- 1 reg /none mem rex
- %0F
- %43
- reg mem modrm01
- disp imm8
- } /cmovncqMemDisp8Reg deff
-
- { ==dst ==src
- src bit64assert
- dst bit64assert
-
- 1 dst /none src rex
- %0F
- %4E
- dst src modrm11
- } /cmovngqRegReg deff
-
- { ==dst ==src
- src bit64assert
- dst bit64assert
-
- 1 dst /none src rex
- %0F
- %4D
- dst src modrm11
- } /cmovgeqRegReg deff
-
- { ==dst ==src
- src bit64assert
- dst bit64assert
-
- 1 dst /none src rex
- %0F
- %4C
- dst src modrm11
- } /cmovngeqRegReg deff
-
- { ==dst ==src
- src bit64assert
- dst bit64assert
-
- 1 dst /none src rex
- %0F
- %45
- dst src modrm11
- } /cmovnzqRegReg deff
-
- { ==dst ==src
- src bit64assert
- dst bit64assert
-
- 1 dst /none src rex
- %0F
- %44
- dst src modrm11
- } /cmovzqRegReg deff
-
- {
- %A6
- } /cmpsb deff
-
- {
- 1 /none /none /none rex
- %A7
- } /cmpsq deff
-
- { ==mem ==reg
- reg bit32assert
- mem bit64assert
-
- reg regno %07 gt mem regno %07 gt or { 0 reg /none mem rex } rep
- %39
- reg mem modrm00
- } /cmplRegMem deff
-
- /cmp %38 defAsmAddb
- /cmp %39 defAsmAddq
- /cmp /seven defAsmAddImm
-
- { ==mem
- mem bit64assert
-
- 1 /none /none mem rex
- %FF
- /one mem modrm00
- } /decqMem deff
-
- { ==reg
- reg bit64assert
-
- 1 /none /none reg rex
- %FF
- /one reg modrm11
- } /decqReg deff
-
- { ==reg
- reg bit64assert
-
- 1 /none /none reg rex
- %F7
- /six reg modrm11
- } /divqReg deff
-
- { ==reg
- reg bit8assert
-
- 1 /none /none reg rex
- %FE
- /zero reg modrm11
- } /incbReg deff
-
- { ==mem
- mem bit64assert
-
- 1 /none /none mem rex
- %FF
- /zero mem modrm00
- } /incqMem deff
-
- { ==reg
- reg bit64assert
-
- 1 /none /none reg rex
- %FF
- /zero reg modrm11
- } /incqReg deff
-
- /loop %E2 defJmpRel8
-
- /jmp %EB defJmpRel8
-
- { ==lbl
- "opcode only exists on AMD cpus (and has 'interesting' semantics even there)" die
- width16
- %E9
- lbl labelRel16
- } /jmpLbl16 deff
-
- { ==lbl
- %E9
- lbl labelRel32
- } /jmpLbl32 deff
-
- /ja _ %77 defJmpRel8 %87 defJmpRel32
- /jae _ %73 defJmpRel8 %83 defJmpRel32
- /jb _ %72 defJmpRel8 %82 defJmpRel32
- /jc _ %72 defJmpRel8 %82 defJmpRel32
- /jbe _ %76 defJmpRel8 %86 defJmpRel32
- /je _ %74 defJmpRel8 %84 defJmpRel32
- /jg _ %7F defJmpRel8 %8F defJmpRel32
- /jge _ %7D defJmpRel8 %8D defJmpRel32
- /jl _ %7C defJmpRel8 %8C defJmpRel32
- /jle _ %7E defJmpRel8 %8E defJmpRel32
- /jnb _ %73 defJmpRel8 %83 defJmpRel32
- /jnc _ %73 defJmpRel8 %83 defJmpRel32
- /jne _ %75 defJmpRel8 %85 defJmpRel32
- /jng _ %7E defJmpRel8 %8E defJmpRel32
- /jnl _ %7D defJmpRel8 %8D defJmpRel32
- /jnge _ %7C defJmpRel8 %8C defJmpRel32
- /jnle _ %7F defJmpRel8 %8F defJmpRel32
- /jns _ %79 defJmpRel8 %89 defJmpRel32
- /jno _ %71 defJmpRel8 %81 defJmpRel32
- /jnz _ %75 defJmpRel8 %85 defJmpRel32
- /js _ %78 defJmpRel8 %88 defJmpRel32
- /jo _ %70 defJmpRel8 %80 defJmpRel32
- /jz _ %74 defJmpRel8 %84 defJmpRel32
-
- { ==reg
- reg bit64assert
-
- reg regno %07 gt { 1 /none /none reg rex } rep
- %FF
- /four reg modrm11
- } /jmpqReg deff
-
- memoryAddressingVariants keys { ==variant memoryAddressingVariants variant . =*parse
- { parse ==mem
- mem .base regno %07 gt mem .idx regno %07 gt or
- { 0 /none mem .idx mem .base rex } rep
- %FF
- /four mem .encode
- } /jmpq variant defOp
- } each
-
- { ==reg ==mem ==idx ==scale ==disp
- reg bit32assert
- mem bit64assert
- idx bit64assert
- disp 128 lt not { "Disp8 out of range" die } rep
-
- reg regno %07 gt mem regno %07 gt idx regno %07 gt or or { 0 reg idx mem rex } rep
- %8D
- reg /sib modrm01
- scale idx mem sib
- disp imm8
- } /lealMemIndexScaleDisp8Reg deff
-
- memoryAddressingVariants keys { ==variant memoryAddressingVariants variant . =*parse
- { ==reg parse ==mem
- reg bit64assert
-
- 1 reg mem .idx mem .base rex
- %8D
- reg mem .encode
- } /leaq variant /Reg cat defOp
- } each
-
- { ==mem ==i
- mem bit64assert
- i 256 lt not { "Imm8 too large" die } rep
-
- mem regno %07 gt { 0 /none /none mem rex } rep
- %C6
- /zero mem modrm00
- i imm8
- } /movbImmMem deff
-
- { ==mem ==disp ==i
- mem bit64assert
- disp 128 lt not { "Disp8 out of range" die } rep
- i 256 lt not { "Imm8 too large" die } rep
-
- mem regno %07 gt { 0 /none /none mem rex } rep
- %C6
- /zero mem modrm01
- disp imm8
- i imm8
- } /movbImmMemDisp8 deff
-
- { ==mem ==i
- mem bit64assert
- i 65536 lt not { "Imm16 too large" die } rep
-
- width16
- mem regno %07 gt { 0 /none /none mem rex } rep
- %C7
- /zero mem modrm00
- i imm16
- } /movwImmMem deff
-
- { ==mem ==i
- mem bit64assert
- i 65536 65536 mul lt not { "Imm32 too large" die } rep
-
- mem regno %07 gt { 0 /none /none mem rex } rep
- %C7
- /zero mem modrm00
- i imm32
- } /movlImmMem deff
-
- { ==mem ==disp ==i
- mem bit64assert
- disp 128 lt not { "Disp8 out of range" die } rep
- i 65536 65536 mul lt not { "Imm32 too large" die } rep
-
- mem regno %07 gt { 0 /none /none mem rex } rep
- %C7
- /zero mem modrm01
- disp imm8
- i imm32
- } /movlImmMemDisp8 deff
-
- { ==reg ==i
- reg bit64assert
-
- 1 /none /none reg rex
- %B8 reg regno %07 band add
- i imm64
- } /movqImmReg deff
-
- { ==mem ==disp ==i
- mem bit64assert
- i 2147483648 lt not { "Imm32 too small" die } rep
- i 2147483648 neg ge not { "Imm32 too large" die } rep
-
- 1 /none /none mem rex
- %C7
- /zero mem modrm01
- disp imm8
- i imm32
- } /movqImm32MemDisp8 deff
-
- { ==reg
- reg bit64assert
-
- 1 /none /none reg rex
- %B8 reg regno %07 band add
- } /movqImmOOBReg deff
-
- /mov %88 defAsmAddb
- /mov %89 defAsmAddl
- /mov %89 defAsmAddq
-
- {
- %A4
- } /movsb deff
-
- {
- width16
- %A5
- } /movsw deff
-
- {
- %A5
- } /movsl deff
-
- {
- 1 /none /none /none rex
- %A5
- } /movsq deff
-
- { ==dst ==src
- dst bit64assert
- src bit8assert
-
- 1 dst /none src rex
- %0F
- %BE
- dst src modrm11
- } /movsxbqRegReg deff
-
- { ==dst ==src
- dst bit64assert
- src bit16assert
-
- 1 dst /none src rex
- %0F
- %BF
- dst src modrm11
- } /movsxwqRegReg deff
-
- { ==dst ==src
- dst bit64assert
- src bit32assert
-
- 1 dst /none src rex
- %63
- dst src modrm11
- } /movsxlqRegReg deff
-
- { ==dst ==src
- dst bit64assert
- src bit8assert
-
- 1 dst /none src rex
- %0F
- %B6
- dst src modrm11
- } /movzxbqRegReg deff
-
- { ==dst ==src
- dst bit64assert
- src bit16assert
-
- 1 dst /none src rex
- %0F
- %B7
- dst src modrm11
- } /movzxwqRegReg deff
-
- { ==reg ==mem
- reg bit64assert
- mem bit64assert
-
- 1 reg /none mem rex
- %0F
- %B6
- reg mem modrm00
- } /movzxMem8Reg64 deff # TODO: this is a weird name, should be movzxbqMemReg
-
- { ==reg ==mem ==disp
- reg bit64assert
- mem bit64assert
- disp 128 lt not { "Disp8 out of range" die } rep
-
- 1 reg /none mem rex
- %0F
- %B6
- reg mem modrm01
- disp imm8
- } /movzxMem8Disp8Reg64 deff # TODO: this is a weird name, should be movzxbqMemDisp8Reg
-
- { ==reg ==mem ==idx ==scale ==disp
- reg bit64assert
- mem bit64assert
- idx bit64assert
- disp 128 lt not { "Disp8 out of range" die } rep
-
- 1 reg idx mem rex
- %0F
- %B6
- reg /sib modrm01
- scale idx mem sib
- disp imm8
- } /movzxMem8IndexScaleDisp8Reg64 deff # TODO: this is a weird name, should be movzxbqMemIndexScaleDisp8Reg
-
- { ==reg
- reg bit64assert
-
- 1 /none /none reg rex
- %F7
- /four reg modrm11
- } /mulqReg deff
-
- { ==reg
- reg bit64assert
-
- 1 /none /none reg rex
- %F7
- /three reg modrm11
- } /negqReg deff
-
- {
- %90
- } /nop deff
-
- { ==reg
- reg bit64assert
-
- 1 /none /none reg rex
- %F7
- /two reg modrm11
- } /notqReg deff
-
- /or %08 defAsmAddb
- /or %09 defAsmAddq
- /or /one defAsmAddImm
-
- { ==reg
- reg regno %07 gt { 1 /none /none reg rex } rep
- %58 reg regno %07 band add
- } /popqReg deff
-
- { ==reg
- reg regno %07 gt { 1 /none /none reg rex } rep
- %50 reg regno %07 band add
- } /pushqReg deff
-
- memoryAddressingVariants keys { ==variant memoryAddressingVariants variant . =*parse
- { parse ==mem
- mem .base regno %07 gt mem .idx regno %07 gt or { 1 /none mem .idx mem .base rex } rep
- %8F
- /zero mem .encode
- } /popq variant defOp
-
- { parse ==mem
- mem .base regno %07 gt mem .idx regno %07 gt or { 1 /none mem .idx mem .base rex } rep
- %FF
- /six mem .encode
- } /pushq variant defOp
- } each
-
- { ==imm
- %68
- imm imm32
- } /pushqImm32 deff
-
- {
- %F3
- } /reprcx deff
-
- {
- %F2
- } /repnz deff
-
- {
- %F3
- } /repz deff
-
- {
- %C3
- } /retn deff
-
- { ==reg
- reg bit8assert
-
- reg regno %07 gt reg rexreqbyte or { 0 reg /none /none rex } rep
- %D2
- /zero reg modrm11
- } /rolbClReg deff
-
- { ==reg
- reg bit64assert
-
- 1 /none /none reg rex
- %D3
- /zero reg modrm11
- } /rolqClReg deff
-
- {
- %AE
- } /scasb deff
-
- {
- 1 /none /none /none rex
- %AF
- } /scasq deff
-
- { ==reg
- reg regno %07 gt reg rexreqbyte or { 0 reg /none /none rex } rep
- %0F
- %92
- /zero reg modrm11
- } /setcbReg deff
-
- { ==reg
- reg bit64assert
-
- 1 /none /none reg rex
- %D3
- /four reg modrm11
- } /shlqClReg deff
-
- { ==reg ==i
- reg bit64assert
- i 64 lt not { "Shift immediate too large" die } rep
-
- 1 /none /none reg rex
- %C1
- /four reg modrm11
- i imm8
- } /shlqImm8Reg deff
-
- { ==reg
- reg bit64assert
-
- 1 /none /none reg rex
- %D1
- /five reg modrm11
- } /shrq1Reg deff
-
- { ==reg
- reg bit64assert
-
- 1 /none /none reg rex
- %D3
- /five reg modrm11
- } /shrqClReg deff
-
- { ==reg ==i
- reg bit64assert
- i 64 lt not { "Shift immediate too large" die } rep
-
- 1 /none /none reg rex
- %C1
- /five reg modrm11
- i imm8
- } /shrqImm8Reg deff
-
- {
- %AA
- } /stosb deff
-
- {
- 1 /none /none /none rex
- %AB
- } /stosq deff
-
- { ==reg ==mem
- reg bit32assert
- mem bit64assert
-
- reg regno %07 gt mem regno %07 gt or { 0 reg /none mem rex } rep
- %2B
- reg mem modrm00
- } /sublMemReg deff
-
- /sub %29 defAsmAddq
- /sub /five defAsmAddImm
-
- {
- %0F %05
- } /syscall deff
-
- { ==mem ==idx ==scale ==reg
- reg bit8assert
- mem bit64assert
- idx bit64assert
-
- reg regno %07 gt reg rexreqbyte mem regno %07 gt idx regno %07 gt or or or { 0 reg idx mem rex } rep
- %84
- reg /sib modrm00
- scale idx mem sib
- } /testbRegMemIndexScale deff
-
- { ==reg ==i
- reg bit8assert
- i 256 lt not { "Imm8 too large" die } rep
-
- reg regno %07 gt reg rexreqbyte or { 0 /none /none reg rex } rep
- %F6
- /zero reg modrm11
- i imm8
- } /testbImmReg deff
-
- { ==dst ==src
- dst bit64assert
- src bit64assert
-
- 1 src /none dst rex
- %85
- src dst modrm11
- } /testqRegReg deff
-
- { ==mem ==idx ==scale ==reg
- reg bit64assert
- mem bit64assert
- idx bit64assert
-
- 1 reg idx mem rex
- %85
- reg /sib modrm00
- scale idx mem sib
- } /testqRegMemIndexScale deff
-
- {
- %0F
- %0B
- } /ud2 deff
-
- { ==dst ==src
- dst bit64assert
- src bit64assert
-
- 1 src /none dst rex
- %87
- src dst modrm11
- } /xchgqRegReg deff
-
- memoryAddressingVariants keys { ==variant memoryAddressingVariants variant . =*parse
- { parse ==mem ==reg
- reg bit64assert
-
- 1 reg mem .idx mem .base rex
- %87
- reg mem .encode
- } /xchgqReg variant defOp
- } each
-
- /xor %31 defAsmAddq
+ "elymasAsmOps.ey" include
# map "anonymous" allocations away from interpreter heap
diff --git a/compiler/elymasGlobal.ey b/compiler/elymasGlobal.ey
index ba1cbca..4bc5075 100644
--- a/compiler/elymasGlobal.ey
+++ b/compiler/elymasGlobal.ey
@@ -2146,6 +2146,38 @@
:retn
]] /ey.? defv
+ # test whether a scope member exists without following parent pointers
+ # 0 -> member name
+ # 1 -> scope
+ # 0 <- 1 if scope member exists directly in scope, 0 otherwise
+ [[
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem
+
+ /rsi :popqReg # fetch identifier
+ /rdi :popqReg # fetch scope
+ ::internalResolve /rax :movqImmReg
+ /rax :callqReg
+
+ /rax /rax :testqRegReg
+ /unresolvedZero :jzLbl8
+ /rdi /rdi :testqRegReg
+ /unresolved :jnzLbl8
+ 1 /rax :movqImmReg
+ /resolved :jmpLbl8
+
+ @unresolved
+ /rax /rax :xorqRegReg
+ @unresolvedZero
+ @resolved
+ 63 /rax :btsqImm8Reg
+ /rax :pushqReg
+
+ /r15 :pushqMem
+ 8 /r15 :addqImm8Reg
+ :retn
+ ]] /ey.?' defv
+
# enumerate scope keys
# 0 -> scope
# 0 <- array of keys
diff --git a/compiler/elymasLexer.ey b/compiler/elymasLexer.ey
index 411e7ad..65df806 100644
--- a/compiler/elymasLexer.ey
+++ b/compiler/elymasLexer.ey
@@ -4,7 +4,18 @@
assembler .|label "@" deff
"%" _ : -01 deff
- { .value elymas .base10decode ==v
+ <
+ [ /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 ] ==digits
+
+ { 0 ==result
+ { "(.)(.*)" regex } {
+ { streq }_ digits -01 index result 10 mul add =result
+ } loop
+ result
+ }
+ > -- /base10decode deff
+
+ { .value base10decode ==v
v 4294967296 lt {
[
# load value
diff --git a/compiler/elymasTokenize.ey b/compiler/elymasTokenize.ey
index aaf7630..ef938d0 100644
--- a/compiler/elymasTokenize.ey
+++ b/compiler/elymasTokenize.ey
@@ -1,15 +1,4 @@
<
- <
- [ /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 ] ==digits
-
- { 0 ==result
- { "(.)(.*)" regex } {
- { streq }_ digits -01 index result 10 mul add =result
- } loop
- result
- }
- > -- /base10decode deff
-
{ ==f =*re _ ==s re f { s } ? * } /rxparse deffd
{ ==TOKID ==TOKSTR ==TOKINT
diff --git a/compiler/standard.ey b/compiler/standard.ey
index dedbe6b..7cc96ed 100644
--- a/compiler/standard.ey
+++ b/compiler/standard.ey
@@ -6,15 +6,15 @@
|deffc "=*:" deffd
{ "}" | *
- { /f deff /x defv
+ { =*f ==x
{ x f }
} quoted { } { * } ? *
} "}_" defq
-{
- { -01 < ==o { o -01 . } > -12 }" quoted { }" { * }" ? *
+{ { -01 < ==o { o -01 . } > -12 } } {
+ quoted { }" { * }" ? *
quoted { |deffst } { deffst }" ? *
-}" /via defq
+}" ; /via defq
{ -1110 ; ==f =*a len _
{
diff --git a/compiler/standardClient.ey b/compiler/standardClient.ey
index 8d47ad8..47e9cc2 100644
--- a/compiler/standardClient.ey
+++ b/compiler/standardClient.ey
@@ -23,6 +23,9 @@
[ TERM p ]
] } /terminal deffd
+ { -- 1 }" terminal ==:TERMANY
+ { { eq }_ terminal } =*:TERMCHAR
+
{ ==?i ==?a [
[ SAVE i 2 mul ]
a _ len dearray
@@ -156,7 +159,7 @@
}' ? *
set terminal =a
} { ^. } {
- { -- 1 }" terminal =a
+ TERMANY =a
tail
} { ^^ } {
[ [ FIRST ] ] =a
@@ -183,7 +186,7 @@
"invalid character '" "' after \\ in regex" -120 cat cat die
} ] conds
} { 1 } {
- _ head { eq }_ terminal =a
+ _ head TERMCHAR =a
tail
} ] conds
@@ -775,12 +778,10 @@
# global extensions
<
- [ /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /A /B /C /D /E /F ] ==:base16singleDigits
- [ base16singleDigits { ==first base16singleDigits { first -01 cat } each } each ] ==:base16digits
+ "0123456789ABCDEF" ==:base16digits
{
- [ -01 8 { _ 256 mod base16digits * -01 256 div } rep -- ]
- reverse |cat fold
+ [ -01 16 { _ 16 mod base16digits * -01 16 div } rep -- ] reverse str .fromArray
} /base16encode64 deffd
{ ==indent _ ==o
@@ -1025,9 +1026,15 @@
# no long-term stack use here as the executed program uses it as well
{ scope
+ 0 "0" * ==:zero
+ { 0 ==result
+ { zero sub result 10 mul add =result } each
+ result
+ } /base10decode deffd
+
{ ==currentScope ==input
{ .value currentScope sys .executeIdentifier =currentScope } /TOKID defvd
- { .value elymas .base10decode } /TOKINT defvd
+ { .value base10decode } /TOKINT defvd
{ .value } /TOKSTR defvd
{
diff --git a/elymas/lib/sys/opt.ey b/elymas/lib/sys/opt.ey
index 9da4424..a59886f 100644
--- a/elymas/lib/sys/opt.ey
+++ b/elymas/lib/sys/opt.ey
@@ -1,10 +1,24 @@
<
+ txt .consume .|hu "%" deffd
+
<
- "../compiler/elymasAsm.ey" include
- assembler /ops sys .asm .defv
- > --
+ "../compiler/elymasAsmOps.ey" include
+ > /ops sys .asm .defv
- sys .asm .ops ":" via
+ sys .asm .ops ==:sysasmops
+ {
+ quoted {
+ _ sys .typed .type 1 eq {
+ sysasmops -01 .|
+ } {
+ "sysasmops" "|" | -102 "." |
+ } ? *
+ } {
+ sysasmops -01 .
+ } ? *
+ } ":" defq
+ sys .asm "::" via
+ sys .asm .|peek ==:peek
[
8 /r15 :subqImm8Reg
@@ -147,8 +161,6 @@
] any
} /holdsInt deffd
- { -1010 lt -012 ? } /max deffd
-
{ ==o ==executingScope
0 ==containsScopeModifications # TODO: replace <, > by macros ( {, scope } * respectively) then remove this
@@ -233,7 +245,7 @@
{ 0 secondLast * STATICTYPED streq }' andif
}' {
1 last * ::rawObject ==constant
- 4 secondLast * ::rawObject ==relevantScope
+ 4 secondLast * ==relevantScope
constant relevantScope sys .resolveInfo {
==mode -- ==parentCount 32 add ==offsetInScope ==inExtensionArea
@@ -411,7 +423,7 @@
{ 1 entry * "*" | ::rawCodeAddress eq }' andif
{ 0 last * STATICTYPED streq }' andif
}' {
- 4 last * ::rawObject ==executedObject
+ 4 last * ==executedObject
executedObject sys .typed .type ==type
type [
@@ -544,9 +556,6 @@
} each last ]
} /rewriteSimpleFunctions deffst
- sys .asm "::" via
- sys .asm .|peek ==:peek
-
o ::rawAddress ==addr
[ addr _ 4 add range peek each ] 256 math .unbase ==totalLength
[ addr 8 add _ 4 add range peek each ] 256 math .unbase ==codeLength
@@ -586,6 +595,10 @@
calledAddress ==j
{ { j }' { =j }' peek generalMatch }' /callTargetMatch deff
[
+ { calledAddress 105553116266496 lt }' { # HEAPBASE # FIXME: should use global constant
+ [ CALL calledAddress ] emitLogic
+ }
+
{ constantActiveGeneralPattern callTargetMatch }' {
[ calledAddress 3 add _ 8 add range peek each ] 256 math .unbase ==calledConstant
@@ -624,7 +637,7 @@
{ staticLoadFromScopePattern callTargetMatch }' {
[ loadStart 4 add _ 4 add range peek each ] 256 math .unbase ==offsetInScope
[ calledAddress 8 sub _ 8 add range peek each ] 256 math .unbase ==exampleObjectOffset
- [ calledAddress exampleObjectOffset add _ 8 add range peek each ] 256 math .unbase ==exampleObject
+ [ calledAddress exampleObjectOffset add _ 8 add range peek each ] 256 math .unbase ::rawObject ==exampleObject
[ STATICTYPED offsetInScope parentCount 0 exampleObject ] emitLogic
}
@@ -632,7 +645,7 @@
{ staticLoadFromExtensionPattern callTargetMatch }' {
[ loadStart 14 add _ 4 add range peek each ] 256 math .unbase ==offsetInScope
[ calledAddress 8 sub _ 8 add range peek each ] 256 math .unbase ==exampleObjectOffset
- [ calledAddress exampleObjectOffset add _ 8 add range peek each ] 256 math .unbase ==exampleObject
+ [ calledAddress exampleObjectOffset add _ 8 add range peek each ] 256 math .unbase ::rawObject ==exampleObject
[ STATICTYPED offsetInScope parentCount 1 exampleObject ] emitLogic
}
@@ -926,6 +939,10 @@
newOpcodes newReferences o ::replace
1 executingScope # return something different from o to signal successful optimization
+
+ [ ] _ =newOpcodes
+ _ =newReferences
+ =newLogic
} /optimize deffd
0 ==recursionDepth
@@ -937,4 +954,15 @@
} /hook sys .opt .deff
> --
+# ensure that the optimizer is run often enough to finish optimize itself
+# while in practice this is also achieved by the next freeze, it should be done explicitely
+100 { scope ==s
+ "{" s sys .executeIdentifier =s
+ 1 1
+ "add" s sys .executeIdentifier =s
+ "--" s sys .executeIdentifier =s
+ "}" s sys .executeIdentifier =s
+ *
+} rep
+
# vim: syn=elymas
diff --git a/elymas/lib/sys/so.ey b/elymas/lib/sys/so.ey
index d474d4c..468ec0f 100644
--- a/elymas/lib/sys/so.ey
+++ b/elymas/lib/sys/so.ey
@@ -572,7 +572,7 @@
i sys .asm .globalAllocSize ==?dataSize
>
} each
- ] ==allocSections
+ ] ==?allocSections
4096 ==:PAGESIZE
@@ -840,10 +840,11 @@
data str .fromArray out .writeall
} each
+ 1 ==:WRITE
+
[ ] _ =fileHeaders
=metaSections
-
- 1 ==:WRITE
+ < > =stringTable
allocSections { ==section
section .dataOffset fileOffset sub str .alloc out .writeall
diff --git a/elymas/loaded.ey b/elymas/loaded.ey
index f917b62..02faa8a 100644
--- a/elymas/loaded.ey
+++ b/elymas/loaded.ey
@@ -2,8 +2,6 @@
[
"lib/bin.ey"
- "lib/txt.ey"
- "lib/math.ey"
"lib/sys/linux.ey"
"lib/net.ey"
"lib/net/tcp.ey"
diff --git a/elymas/memdump.ey b/elymas/memdump.ey
index d86f095..ef43d52 100644
--- a/elymas/memdump.ey
+++ b/elymas/memdump.ey
@@ -71,7 +71,7 @@ ELFBASE 56 add peek64 65536 mod _ dump ==phdrCount
} eachWhile
} /peekElf64 deffst
-HEAPBASE peekElf64 %2E00000000000248 eq assert
+HEAPBASE peekElf64 %FFFFFFFFFFFF0000 band %2E00000000000000 eq assert
sys .asm .|programStart sys .asm .rawCodeAddress { add peekElf64 }_ =*peekProgramStart
2 peekProgramStart _ dump ==initialRsp
diff --git a/elymas/optimized.ey b/elymas/optimized.ey
index f64504e..5cee305 100644
--- a/elymas/optimized.ey
+++ b/elymas/optimized.ey
@@ -2,6 +2,7 @@
[
"lib/math.ey"
+ "lib/txt.ey"
"lib/sys/opt.ey"
] { _ dump include }' each
diff --git a/elymas/shared.ey b/elymas/shared.ey
index 212c506..6a0ee6d 100644
--- a/elymas/shared.ey
+++ b/elymas/shared.ey
@@ -2,8 +2,6 @@
[
"lib/bin.ey"
- "lib/txt.ey"
- "lib/math.ey"
"lib/sys/linux.ey"
"lib/sys/so.ey"
"lib/net.ey"