aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/elymasAsm.ey113
-rw-r--r--compiler/elymasAsmLib.ey170
-rw-r--r--examples/working/stackops.ey1
-rw-r--r--examples/working/string.ey1
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