diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/elymasAsm.ey | 1249 | ||||
| -rw-r--r-- | compiler/elymasGlobal.ey | 32 | ||||
| -rw-r--r-- | compiler/elymasLexer.ey | 13 | ||||
| -rw-r--r-- | compiler/elymasTokenize.ey | 11 | ||||
| -rw-r--r-- | compiler/standard.ey | 8 | ||||
| -rw-r--r-- | compiler/standardClient.ey | 21 |
6 files changed, 63 insertions, 1271 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 { |
