diff options
| -rw-r--r-- | compiler/elymasAsm.ey | 113 | ||||
| -rw-r--r-- | compiler/elymasAsmLib.ey | 170 | ||||
| -rw-r--r-- | examples/working/stackops.ey | 1 | ||||
| -rw-r--r-- | examples/working/string.ey | 1 |
4 files changed, 238 insertions, 47 deletions
diff --git a/compiler/elymasAsm.ey b/compiler/elymasAsm.ey index a793a16..62776ab 100644 --- a/compiler/elymasAsm.ey +++ b/compiler/elymasAsm.ey @@ -124,6 +124,25 @@ opcodes } /labelResolve deff + { < ==name ==opcode + { ==offset + offset 128 neg ge assert + offset 128 lt assert + + opcode + offset imm8 + } name "Rel8" cat + + { ==lbl + + opcode + lbl labelRel8 + _ 128 neg ge assert + _ 128 lt assert + } name "Lbl8" cat + > -- 2 |deff rep + }' /defJmp deff + # instructions { ==reg ==mem reg bit32assert @@ -175,6 +194,15 @@ src dst modrm11 } /addqRegReg deff + { ==dst ==src + dst bit64assert + src bit64assert + + 1 src /none dst rex + %21 + src dst modrm11 + } /andqRegReg deff + { ==reg reg bit64assert @@ -183,6 +211,16 @@ /two reg modrm11 } /callqReg deff + { ==dst ==src + src bit64assert + dst bit64assert + + 1 dst /none src rex + %0F + %47 + dst src modrm11 + } /cmovaqRegReg deff + { %A6 } /cmpsb deff @@ -201,6 +239,16 @@ reg mem modrm00 } /cmplRegMem deff + { ==reg ==i + reg bit64assert + i 256 lt assert + + 1 /none /none reg rex + %83 + /seven reg modrm11 + i imm8 + } /cmpqImm8Reg deff + { ==mem ==reg reg bit64assert mem bit64assert @@ -227,34 +275,30 @@ /zero reg modrm11 } /incqReg deff - { < ==name ==opcode - { ==offset - offset 128 neg ge assert - offset 128 lt assert - - opcode - offset imm8 - } name "Rel8" cat - - { ==lbl - - opcode - lbl labelRel8 - _ 128 neg ge assert - _ 128 lt assert - } name "Lbl8" cat - > -- 2 |deff rep - }' /defJmp deff + %E2 /loop defJmp %EB /jmp defJmp %72 /jb defJmp %76 /jbe defJmp + %74 /je defJmp %7E /jle defJmp %73 /jnb defJmp + %75 /jne defJmp %75 /jnz defJmp %74 /jz defJmp + { ==reg ==mem ==disp + reg bit64assert + mem bit64assert + disp 128 lt assert + + 1 reg /none mem rex + %8D + reg mem modrm01 + disp imm8 + } /leaqMemDisp8Reg deff + { ==reg ==mem reg bit32assert mem bit64assert @@ -362,6 +406,16 @@ src dst modrm11 } /movqRegReg deff + { ==reg ==mem + reg bit64assert + mem bit64assert + + 1 reg /none mem rex + %0F + %B6 + reg mem modrm00 + } /movzxMem8Reg64 deff + { ==mem ==i mem bit64assert i 256 lt assert @@ -382,12 +436,28 @@ i imm8 } /orbImmMemDisp8 deff + { ==dst ==src + dst bit64assert + src bit64assert + + 1 src /none dst rex + %09 + src dst modrm11 + } /orqRegReg deff + { ==mem mem regno %07 gt { 1 /none /none mem rex } rep %8F /zero mem modrm00 } /popqMem deff + { ==mem ==idx ==scale + mem regno %07 gt idx regno %07 gt or { 1 /none idx mem rex } rep + %8F + /zero /sib modrm00 + scale idx mem sib + } /popqMemIndexScale deff + { ==reg reg regno %07 gt { 1 /none /none reg rex } rep %58 reg regno %07 band add @@ -399,6 +469,13 @@ /six mem modrm00 } /pushqMem deff + { ==mem ==idx ==scale + mem regno %07 gt idx regno %07 gt or { 1 /none idx mem rex } rep + %FF + /six /sib modrm00 + scale idx mem sib + } /pushqMemIndexScale deff + { ==reg reg regno %07 gt { 1 /none /none reg rex } rep %50 reg regno %07 band add diff --git a/compiler/elymasAsmLib.ey b/compiler/elymasAsmLib.ey index 91cad72..598be33 100644 --- a/compiler/elymasAsmLib.ey +++ b/compiler/elymasAsmLib.ey @@ -2,6 +2,7 @@ < { assembler -01 . } ":" deff + assembler .|label "@" deff "%" _ : -01 deff < @@ -51,7 +52,7 @@ :repz :cmpsb /fail :jnzLbl8 /rax :incqReg - /fail :label + @fail ] :labelResolve /internalStringEqualsCode defv < @@ -118,7 +119,7 @@ 16 /rdx :addqImm8Reg # rdx will iterate over entries 8 /rcx /rcx :addqMemDisp8Reg # compute name table effective end - /loop :label + @loop /rdx /rcx :cmpqRegReg /end :jbeLbl8 # TODO this is ridiculous @@ -138,7 +139,7 @@ 16 /rdx :addqImm8Reg /loop :jmpLbl8 - /end :label + @end # not found at all, retry with parent # FIXME: Actually try with parent @@ -146,7 +147,7 @@ /rdx /rdx :xorqRegReg :retn - /found :label + @found 8 /rdx /rax :movqMemDisp8Reg # load default activation 8 /rdi /rdx :subqMemDisp8Reg # substract name table start 16 /rdx :subqImm8Reg # substract name table header size @@ -163,7 +164,7 @@ 24 /rdi /rdi :movqMemDisp8Reg # load extension area pointer 8 /rdx :addqImm8Reg # add extension area header length - /inDataArea :label + @inDataArea /rdx /rdi /rdx :movqMemIndexReg # load entry pointer /rax /rdx :xchgqRegReg :retn @@ -239,12 +240,12 @@ ] /internalAllocateFunction defv > { defv }' allocateOffsetStruct - < - # elymas functions, stack based ABI + # elymas functions, stack based ABI - # 0 -> integer - # 1 -> integer - # 0 <- sum of the above + # 0 -> integer + # 1 -> integer + # 0 <- sum of the above + { ==opcodes [ /rbx :popqReg @@ -262,14 +263,48 @@ /rdx :popqReg 8 /rdx /rdx :movqMemDisp8Reg - /rcx /rdx :addqRegReg + opcodes _ len dearray /rdx 8 /rax :movqRegMemDisp8 # push int address on program stack /rax :pushqReg /rbx :pushqReg :retn - ] /eyadd defv + ] + } /makeArith deff + + < + # do nothing + [ + :retn + ] /ey/ defv + + # resolve in scope but never execute + [ + /rcx :popqReg + /rax :popqReg + /rcx :pushqReg + /rax :pushqReg + + # scope resolution + currentScope /rdi :movqImmReg + /rdi /rdi :movqMemReg + /rsi :popqReg + internalResolve /rax :movqImmReg + /rax :callqReg + + /rcx :popqReg + /rax :pushqReg + /rcx :pushqReg + :retn + ] /ey| defv + + # arithmetic functions on ints + [ /rcx /rdx :addqRegReg ] makeArith /eyadd defv + [ /rcx /rdx :subqRegReg ] makeArith /eysub defv + [ /rcx /rdx :andqRegReg ] makeArith /eyband defv + [ /rcx /rdx :orqRegReg ] makeArith /eybor defv + [ /rcx /rdx :xorqRegReg ] makeArith /eybxor defv # create a new entry in the current scope for the given name # mark that entry as default-active @@ -286,7 +321,7 @@ 8 /rbx /rsi :movqMemDisp8Reg # rsi == start of nametable in heap 8 /rsi /rsi :addqMemDisp8Reg # rsi == end of nametable in heap (according to fill) - /nameSearch :label + @nameSearch 16 /rdx :addqImm8Reg # rsi: end of nametable @@ -309,7 +344,7 @@ /nameOffsetKnown :jnzLbl8 # if not exists, insert - /nameUndefined :label + @nameUndefined 8 /rbx /rdx :movqMemDisp8Reg # rdx == start of nametable in heap /rdx /eax :movlMemReg # add memory length to obtain memory end /rax /rdx :addqRegReg @@ -325,12 +360,12 @@ /rsi /rdx :movqRegReg /nameOffsetKnown :jmpLbl8 - /enlargeNameTable :label + @enlargeNameTable # if name table is already full, double size # FIXME :ud2 - /nameOffsetKnown :label + @nameOffsetKnown 8 /rbx /rdx :subqMemDisp8Reg # substract name table address 16 /rdx :subqImm8Reg # substract name table header size /rdx :shrq1Reg # divide by 2 to get offset within scope @@ -356,8 +391,8 @@ # FIXME :ud2 - /inExtensionArea :label - /inDataArea :label + @inExtensionArea + @inDataArea /rax :popqReg /rax /rbx /rdx :movqRegMemIndex # save entry pointer @@ -379,7 +414,7 @@ /scoped :jnzLbl8 currentScope /rax :movqImmReg /rax /rcx :movqMemReg - /scoped :label + @scoped 8 /r15 :subqImm8Reg /rcx /r15 :movqRegMem @@ -393,10 +428,10 @@ /rax :callqReg /done :jmpLbl8 - /typed :label + @typed :ud2 # TODO handle typed functions and autolooping - /done :label + @done /r15 /rcx :movqMemReg currentScope /rax :movqImmReg /rcx /rax :movqRegMem @@ -406,23 +441,98 @@ :retn ] :labelResolve /ey* defv - # drop top stack element + # dump top stack element (actually drop it for now) + # FIXME: this belongs in the standard library [ /rax :popqReg /rcx :popqReg /rax :pushqReg :retn - ] /ey-- defv + ] /eydump defv + > _ ==globalFunctions { defv }' allocateOffsetStruct - # dump top stack element (actually drop it for now) - # FIXME: this belongs in the standard library + < + # drop top stack element [ /rax :popqReg /rcx :popqReg /rax :pushqReg :retn - ] /eydump defv - > _ ==globalFunctions { defv }' allocateOffsetStruct + ] /ey-- defv + + # top stack element is a string defining a stack shuffle + # 0-9: push the thusly numbered element + # *: execute top element + # pops as many elements as the highest number specifies + [ + 8 /r15 :subqImm8Reg + /r15 :popqMem + 80 /r15 :subqImm8Reg + + /rdi :popqReg + 16 /rdi /rcx :movqMemDisp8Reg # load string length + 24 /rdi /rax :leaqMemDisp8Reg # rax to begin of string + + 42 /rsi :movqImmReg # initialize with '*' + + # find maximal element, note that '*' < '0' + @maximalElementSearch + /rax /rdx :movzxMem8Reg64 + /rsi /rdx :cmpqRegReg + /rdx /rsi :cmovaqRegReg + /rax :incqReg + /maximalElementSearch :loopLbl8 + + # move elements to temporary storage + 42 /rsi :cmpqImm8Reg + /elementsSaved :jeLbl8 + + 47 /rsi :subqImm8Reg # substract '0'-1 + /rsi /rcx :movqRegReg + /rsi /rsi :xorqRegReg + + @saveElements + 8 /rsi /r15 :popqMemIndexScale + /rsi :incqReg + /saveElements :loopLbl8 + + # execute shuffle specification + @elementsSaved + 16 /rdi /rcx :movqMemDisp8Reg # load string length + 24 /rdi /rax :leaqMemDisp8Reg # rax to begin of string + + @executeSpec + /rax /rdx :movzxMem8Reg64 + /rax :incqReg + + 42 /rdx :cmpqImm8Reg + /executeTop :jeLbl8 + + 48 /rdx :subqImm8Reg # substract '0' + 8 /rdx /r15 :pushqMemIndexScale + /executeSpec :loopLbl8 + /done :jmpLbl8 + + @executeTop + 24 /r15 :subqImm8Reg + /rax 16 /r15 :movqRegMemDisp8 + /rcx 8 /r15 :movqRegMemDisp8 + /rdx /r15 :movqRegMem + |ey* /rax :movqImmReg + /rax :callqReg + /r15 /rdx :movqMemReg + 8 /r15 /rcx :movqMemDisp8Reg + 16 /r15 /rax :movqMemDisp8Reg + 24 /r15 :addqImm8Reg + /executeSpec :loopLbl8 + + @done + 80 /r15 :addqImm8Reg + /r15 :pushqMem + 8 /r15 :addqImm8Reg + :retn + ] :labelResolve /ey- defv + > _ ==globalFunctions2 { defv }' allocateOffsetStruct { strToUTF8Bytes _ =*v len _ ==exactLength 1 sub 8 div 4 add 8 mul ==memoryLength @@ -461,15 +571,17 @@ ] } /constStringCode deff + globalFunctions keys globalFunctions2 keys cat ==globalFunctionNames + [ - globalFunctions keys len /rdi :movqImmReg + globalFunctionNames len /rdi :movqImmReg internalAllocateScope /rax :movqImmReg /rax :callqReg currentScope /rdi :movqImmReg /rax /rdi :movqRegMem - globalFunctions keys { ==name + globalFunctionNames { ==name # create function name | 8 sub /rdi :movqImmReg currentScope /rsi :movqImmReg diff --git a/examples/working/stackops.ey b/examples/working/stackops.ey index 6cd95af..c077adb 100644 --- a/examples/working/stackops.ey +++ b/examples/working/stackops.ey @@ -1,3 +1,4 @@ +1 2 3 -012 -- -- -- [ 1 2 3 ] dump [ 1 2 3 -210 ] dump [ 1 2 3 -012 ] dump diff --git a/examples/working/string.ey b/examples/working/string.ey index 54d1838..142ce49 100644 --- a/examples/working/string.ey +++ b/examples/working/string.ey @@ -3,3 +3,4 @@ "a\\b" dump "a\"b" dump "thisisalongstring" dump +/bare dump |
