aboutsummaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorDrahflow <drahflow@gmx.de>2013-01-10 12:17:00 +0100
committerDrahflow <drahflow@gmx.de>2013-01-10 12:17:00 +0100
commit0107c46dbad1c6f45ae05815df880970fcdb172b (patch)
tree86a61519f2c58b5e6b2f8b14e13ad1829aa05238 /compiler
parentdcf987b6da372b55c36628b88f5d8e70596be6cb (diff)
Running again, with global scope now
Diffstat (limited to 'compiler')
-rw-r--r--compiler/elymasAsm.ey201
-rw-r--r--compiler/elymasAsmLib.ey178
-rw-r--r--compiler/elymasGlobal.ey47
3 files changed, 237 insertions, 189 deletions
diff --git a/compiler/elymasAsm.ey b/compiler/elymasAsm.ey
index 7b5dbf6..ef931e6 100644
--- a/compiler/elymasAsm.ey
+++ b/compiler/elymasAsm.ey
@@ -80,8 +80,11 @@
{ ==base ==idx ==scale
idx [ /spl /sp /esp /rsp ] streq any not assert
base [ /bpl /bp /ebp /rbp ] streq any not assert
+ scale _ 0 gt assert 8 le assert
- %C0 scale %40 mul band add
+ scale [ 1 %00 %40 1 %80 1 1 1 %C0 ] *
+ _ 1 neq assert
+ %C0 band
%38 idx regno 8 mul band add
%07 base regno band add
} /sib deff
@@ -91,16 +94,54 @@
{ _ 0 ge assert 2 { _ 256 mod -01 256 div } rep -- } /imm16 deff
{ _ 0 lt { 256 add } rep 255 band } /imm8 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 assert
+ _ 128 neg ge assert
+ imm8 offset -102 =[] } ] cat =labelHoles
+ [ -011 len dearray %00
+ } /labelRel8 deff
+
+ { ==opcodes
+ labelHoles { opcodes -01 * } each
+
+ < { defv }' /put deff > =labels
+ [ ] =labelHoles
+
+ opcodes
+ } /labelResolve deff
+
# instructions
{ ==reg ==mem
reg bit32 assert
mem bit64 assert
- 0 reg /none mem rex
+ reg regno %07 gt mem regno %07 gt or { 0 reg /none mem rex } rep
%03
reg mem modrm00
} /addlMemReg deff
+ { ==mem ==disp ==i
+ mem bit64 assert
+ i 256 lt assert
+
+ 1 /none /none mem rex
+ %83
+ /zero mem modrm01
+ disp imm8
+ i imm8
+ } /addqImm8MemDisp8 deff
+
{ ==reg ==i
reg bit64 assert
i 256 lt assert
@@ -183,25 +224,42 @@
/zero reg modrm11
} /incqReg deff
- { ==name ==opcode
- {
- ==offset
+ { < ==name ==opcode
+ { ==offset
offset 128 neg ge assert
offset 128 lt assert
opcode
offset imm8
- } name deff
- }' /defRel8Jmp deff
+ } name "Rel8" cat
- %EB /jmpRel8 defRel8Jmp
+ { ==lbl
- %72 /jbRel8 defRel8Jmp
- %76 /jbeRel8 defRel8Jmp
- %7E /jleRel8 defRel8Jmp
- %73 /jnbRel8 defRel8Jmp
- %75 /jnzRel8 defRel8Jmp
- %74 /jzRel8 defRel8Jmp
+ opcode
+ lbl labelRel8
+ _ 128 neg ge assert
+ _ 128 lt assert
+ } name "Lbl8" cat
+ > -- 2 |deff rep
+ }' /defJmp deff
+
+ %EB /jmp defJmp
+
+ %72 /jb defJmp
+ %76 /jbe defJmp
+ %7E /jle defJmp
+ %73 /jnb defJmp
+ %75 /jnz defJmp
+ %74 /jz defJmp
+
+ { ==reg ==mem
+ reg bit32 assert
+ mem bit64 assert
+
+ reg regno %07 gt mem regno %07 gt or { 0 reg /none mem rex } rep
+ %8B
+ reg mem modrm00
+ } /movlMemReg deff
{ ==reg ==i
reg bit64 assert
@@ -211,6 +269,18 @@
i imm64
} /movqImmReg deff
+ { ==mem ==disp ==i
+ mem bit64 assert
+ i 2147483648 lt assert
+ i 2147483648 neg ge assert
+
+ 1 /none /none mem rex
+ %C7
+ /zero mem modrm01
+ disp imm8
+ i imm32
+ } /movqImm32MemDisp8 deff
+
{ ==reg
reg bit64 assert
@@ -268,7 +338,7 @@
reg mem modrm01
disp imm8
} /movqRegMemDisp8 deff
-
+
{ ==mem ==idx ==reg
reg bit64 assert
mem bit64 assert
@@ -342,14 +412,12 @@
i imm8
} /shlqImm8Reg deff
- { ==reg ==i
+ { ==reg
reg bit64 assert
- i 256 lt assert
1 /none /none reg rex
%D1
/five reg modrm11
- i imm8
} /shrq1Reg deff
{ ==reg ==i
@@ -368,7 +436,7 @@
disp 128 lt assert
1 reg /none mem rex
- %29
+ %2B
reg mem modrm01
disp imm8
} /subqMemDisp8Reg deff
@@ -378,7 +446,7 @@
mem bit64 assert
reg regno %07 gt mem regno %07 gt or { 0 reg /none mem rex } rep
- %29
+ %2B
reg mem modrm00
} /sublMemReg deff
@@ -387,7 +455,7 @@
mem bit64 assert
1 reg /none mem rex
- %29
+ %2B
reg mem modrm00
} /subqMemReg deff
@@ -463,38 +531,6 @@
src dst modrm11
} /xorqRegReg deff
- # label handling
- < { defv }' /put deff > ==labels
- [ ] ==labelHoles
-
- { ==l
- ] _ len l labels .put [ -011 len dearray
- } /label deff
-
- { ==l
- ] _ len ==offset
- labelHoles [ { offset labels l . sub imm8 offset -102 =[] } ] cat =labelHoles
- [ -011 len dearray %00
- } /labelRel8 deff
-
- { ==opcodes
- labelHoles { opcodes -01 * } each
-
- < { defv }' /put deff > =labels
- [ ] =labelHoles
-
- opcodes
- } /labelResolve deff
-
- # data manipulation functions
- { # ==addr
- [ -01 8 { _ sys .asm .peek -01 1 add } rep -- ] reverse { -01 256 mul add } fold
- } /peekImm64 deff
-
- { # ==addr
- [ -01 4 { _ sys .asm .peek -01 1 add } rep -- ] reverse { -01 256 mul add } fold
- } /peekImm32 deff
-
# global stack layout
# 0 - STACKSTART : global variables
# %0 : current stack pointer
@@ -507,65 +543,6 @@
] { i sys .asm .poke i 1 add =i } each
> --
- {
- [ -01 16 { _ 16 mod -01 16 div } rep -- ]
- [ /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /A /B /C /D /E /F ] *
- reverse |cat fold
- } /base16encode64 deff
-
- {
- [ -01 8 { _ 16 mod -01 16 div } rep -- ]
- [ /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /A /B /C /D /E /F ] *
- reverse |cat fold
- } /base16encode32 deff
-
- <
- [
- 32 { "." } rep
- " " "!" "\"" "#" "$" "%" "&" "´" "(" ")" "*" "+" "," "-" "." "/"
- /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 ":" ";" "<" "=" ">" "?"
- "@" /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P
- /Q /R /S /T /U /V /W /X /Y /Z "[" "\\" "]" "^" "_"
- "`" /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p
- /q /r /s /t /u /v /w /x /y /z "{" "|" "}" "~" "."
- 128 { "." } rep
- ] /ASCII defv
-
- {
- mainStack .base STACKSIZE add ==stackEnd
- "Stack ------------\n" sys .out .writestr
- mainStack .base peekImm64 ==addr
- addr stackEnd gt { [ -01 stackEnd ] die } rep # Stack corrupted
-
- { addr stackEnd lt } {
- [
- addr base16encode64 ": "
- addr peekImm64 ==value
- value base16encode64
- value 105553116266496 ge value 123145302310912 lt and {
- value peekImm32
- value 4 add peekImm32 16777215 band 4294967296 mul
- add 8 div ==length
- 0 length 1 sub range {
- 8 mul value add ==heapAddr
- "\n "
- heapAddr base16encode64
- ": "
- # the perl interpreter does not like full 64bit numbers and converts them into floats
- heapAddr 4 add peekImm32 _ ==heapValueB base16encode32
- heapAddr peekImm32 _ ==heapValueA base16encode32
- " "
- [ [ heapValueA heapValueB ] { 4 { _ 256 mod -01 256 div } rep -- } each ] ASCII * 8 dearray
- } each
- } rep
- "\n"
- ] |cat fold sys .out .writestr
- addr 8 add =addr
- } loop
- "^^^^^^^^^^^^^^^^^^\n" sys .out .writestr
- }
- > -- /stackDump deff
-
{ ==opcodes
opcodes len 1 sub PAGESIZE div 1 add PAGESIZE mul sys .asm .alloc /codearea defv
codearea .base ==i
diff --git a/compiler/elymasAsmLib.ey b/compiler/elymasAsmLib.ey
index 423ee71..01aed4f 100644
--- a/compiler/elymasAsmLib.ey
+++ b/compiler/elymasAsmLib.ey
@@ -47,10 +47,10 @@
:cmpsq # ignore hash
/rsi /rdx :movqMemReg # load exact length
:cmpsq # same exact length
- /fail :labelRel8 :jnzRel8
+ /fail :jnzLbl8
/rdx /rcx :movqRegReg
:repz :cmpsb
- /fail :labelRel8 :jnzRel8
+ /fail :jnzLbl8
/rax :incqReg
/fail :label
] :labelResolve /internalStringEqualsCode defv
@@ -101,9 +101,10 @@
# rdi -> address of first string
# rsi -> address of second string
# rax <- 1 if both strings are equal, 0 otherwise
- internalStringEqualsCode [
+ [
+ internalStringEqualsCode _ len dearray
:retn
- ] cat /internalStringEquals defv
+ ] /internalStringEquals defv
# resolve element from scope
# rdi -> address of scope on the heap
@@ -120,24 +121,24 @@
/loop :label
/rdx /rcx :cmpqRegReg
- /end :labelRel8 :jnbRel8
+ /end :jbeLbl8
# TODO this is ridiculous
/rdi :pushqReg
/rsi :pushqReg
/rdx :pushqReg
/rcx :pushqReg
/rdx /rdi :movqMemReg
- ] internalStringEqualsCode [
+ internalStringEqualsCode _ len dearray
/rcx :popqReg
/rdx :popqReg
/rsi :popqReg
/rdi :popqReg
/rax /rax :testqRegReg
- /found :labelRel8 :jnzRel8
+ /found :jnzLbl8
16 /rdx :addqImm8Reg
- /loop :labelRel8 :jmpRel8
+ /loop :jmpLbl8
/end :label
# not found at all, retry with parent
@@ -157,7 +158,7 @@
32 /rdx :addqImm8Reg # add scope header size
/edx /rdi :cmplRegMem # TODO this fails for > 4 GB scopes
- /inDataArea :labelRel8 :jbRel8
+ /inDataArea :jnbLbl8
/rdi /edx :sublMemReg # substract scope length
24 /rdi /rdi :movqMemDisp8Reg # load extension area pointer
@@ -167,7 +168,7 @@
/rdx /rdi /rdx :movqMemIndexReg # load entry pointer
/rax /rdx :xchgqRegReg
:retn
- ] cat cat :labelResolve /internalResolve defv
+ ] :labelResolve /internalResolve defv
> { defv }' allocateOffsetStruct
@@ -188,13 +189,13 @@
# set type
%30 7 /rax :orbImmMemDisp8
- /rdi /rdi :xorqRegReg
- # zero fill
- /rdi 8 /rax :movqRegMemDisp8
- /rax /rcx :movqRegReg
+ # set fill to header size
+ 16 8 /rax :movqImm32MemDisp8
/rdi :popqReg
+ /rax :pushqReg # save name table on the stack
+
3 /rdi :shlqImm8Reg
32 /rdi :addqImm8Reg
internalAllocate /rax :movqImmReg
@@ -203,6 +204,7 @@
# set type and existence of all pointers
%26 7 /rax :orbImmMemDisp8
# reference name table
+ /rcx :popqReg
/rcx 8 /rax :movqRegMemDisp8
# zero parent and extension
/rdi /rdi :xorqRegReg
@@ -275,9 +277,9 @@
# search for name in nametable
currentScope /rax :movqImmReg
/rax /rbx :movqMemReg # rbx == start of scope in heap
- 8 /rbx /rdx :movqRegReg # rdx == start of nametable in heap
+ 8 /rbx /rdx :movqMemDisp8Reg # rdx == start of nametable in heap
8 /rbx /rsi :movqMemDisp8Reg # rsi == start of nametable in heap
- 16 /rdx /rsi :addqMemDisp8Reg # rsi == end of nametable in heap (according to fill)
+ 8 /rsi /rsi :addqMemDisp8Reg # rsi == end of nametable in heap (according to fill)
/nameSearch :label
16 /rdx :addqImm8Reg
@@ -286,47 +288,47 @@
# rdx: current element of nametable
/rdx /rsi :cmpqRegReg
- /nameUndefined :labelRel8 :jnbRel8
+ /nameUndefined :jbeLbl8
/rdx :pushqReg
/rsi :pushqReg
/rdi :pushqReg
/rcx :pushqReg
- /rsi /rsi :movqMemReg
- ] internalStringEqualsCode [
+ /rdx /rsi :movqMemReg
+ internalStringEqualsCode _ len dearray
/rcx :popqReg
/rdi :popqReg
/rsi :popqReg
/rdx :popqReg
/rax /rax :testqRegReg
- /nameSearch :labelRel8 :jzRel8
-
- 8 /rbx /rdx :subqMemDisp8Reg
- 16 /rdx :subqImm8Reg # substract name table header size
- /rdx :shrq1Reg # divide by 2 to get offset within scope
- /nameIndexKnown :labelRel8 :jmpRel8
+ /nameOffsetKnown :jnzLbl8
# if not exists, insert
/nameUndefined :label
- 8 /rbx /rdx :movqRegReg # rdx == start of nametable in heap
- /rdx /edx :addlMemReg # add memory length to obtain memory end
+ 8 /rbx /rdx :movqMemDisp8Reg # rdx == start of nametable in heap
+ /rdx /eax :movlMemReg # add memory length to obtain memory end
+ /rax /rdx :addqRegReg
/rsi /rdx :cmpqRegReg
- /enlargeNameTable :labelRel8 :jnbRel8
+ /enlargeNameTable :jbeLbl8
# insert into name table
/rdi /rsi :movqRegMem
- 1 /rax :movqImmReg
- /rax 8 /rsi :movqRegMemDisp8 # set default activation mode to execute
+ 1 8 /rsi :movqImm32MemDisp8 # set default activation mode to execute
+ 8 /rbx /rdx :movqMemDisp8Reg # rdx == start of nametable in heap
+ 16 8 /rdx :addqImm8MemDisp8 # increment fill
/rsi /rdx :movqRegReg
- /nameIndexKnown :labelRel8 :jmpRel8
+ /nameOffsetKnown :jmpLbl8
/enlargeNameTable :label
# if name table is already full, double size
# FIXME
:ud2
- /nameIndexKnown :label
+ /nameOffsetKnown :label
+ 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
# rdx == offset in scope
# top of stack: the object to store
@@ -335,7 +337,7 @@
# if fits within main area, fine
32 /rdx :addqImm8Reg # add scope header size
/edx /rbx :cmplRegMem # TODO this fails for > 4 GB scopes
- /inDataArea :labelRel8 :jbRel8
+ /inDataArea :jnbLbl8
# update within extension area
/rbx /edx :sublMemReg # substract scope length
@@ -344,7 +346,7 @@
# if extension area is full, double size
/edx /rbx :cmplRegMem
- /inExtensionArea :labelRel8 :jbRel8
+ /inExtensionArea :jnbLbl8
# FIXME
:ud2
@@ -356,7 +358,8 @@
/rax /rbx /rdx :movqRegMemIndex # save entry pointer
/rcx :pushqReg
- ] cat cat :labelResolve /eydeff defv
+ :retn
+ ] :labelResolve /eydeff defv
# execute top element on the stack
[
@@ -365,6 +368,43 @@
] /ey* defv
> _ ==globalFunctions { defv }' allocateOffsetStruct
+ { strToUTF8Bytes _ =*v len _ ==exactLength
+ 1 sub 8 div 4 add 8 mul ==memoryLength
+
+ memoryLength 2147483648 lt assert
+
+ [
+ # allocate string
+ memoryLength /rdi :movqImmReg
+ internalAllocate /rax :movqImmReg
+ /rax :callqReg
+
+ # push string address on program stack
+ /rax :pushqReg
+
+ # set type
+ 7 /rax :addqImm8Reg
+ %10 /rax :orbImmMem
+
+ # clear hash value
+ 1 /rax :addqImm8Reg
+ /rdx /rdx :xorqRegReg
+ /rdx /rax :movqRegMem
+
+ # load exact length
+ 8 /rax :addqImm8Reg
+ exactLength /rdx :movqImmReg
+ /rdx /rax :movqRegMem
+
+ # load string contents
+ 0 exactLength 8 div range { 8 mul ==i
+ 8 /rax :addqImm8Reg
+ /rdx :movqImmOOBReg i _ 7 add range v 8 dearray
+ /rdx /rax :movqRegMem
+ } each
+ ]
+ } /constStringCode deff
+
[
globalFunctions keys len /rdi :movqImmReg
internalAllocateScope /rax :movqImmReg
@@ -385,12 +425,80 @@
/rax :pushqReg
# create string
+ name constStringCode _ len dearray
# enter into current (i.e. global) scope
eydeff /rax :movqImmReg
/rax :callqReg
} each
] :execute
+
+ <
+ [
+ 32 { "." } rep
+ " " "!" "\"" "#" "$" "%" "&" "´" "(" ")" "*" "+" "," "-" "." "/"
+ /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 ":" ";" "<" "=" ">" "?"
+ "@" /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P
+ /Q /R /S /T /U /V /W /X /Y /Z "[" "\\" "]" "^" "_"
+ "`" /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p
+ /q /r /s /t /u /v /w /x /y /z "{" "|" "}" "~" "."
+ 128 { "." } rep
+ ] /ASCII defv
+
+ { # ==addr
+ [ -01 8 { _ sys .asm .peek -01 1 add } rep -- ] reverse { -01 256 mul add } fold
+ } /peekImm64 deff
+
+ { # ==addr
+ [ -01 4 { _ sys .asm .peek -01 1 add } rep -- ] reverse { -01 256 mul add } fold
+ } /peekImm32 deff
+
+ {
+ [ -01 16 { _ 16 mod -01 16 div } rep -- ]
+ [ /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /A /B /C /D /E /F ] *
+ reverse |cat fold
+ } /base16encode64 deff
+
+ {
+ [ -01 8 { _ 16 mod -01 16 div } rep -- ]
+ [ /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /A /B /C /D /E /F ] *
+ reverse |cat fold
+ } /base16encode32 deff
+
+ {
+ :mainStack .base :STACKSIZE add ==stackEnd
+ "Stack ------------\n" sys .out .writestr
+ :mainStack .base peekImm64 ==addr
+ addr stackEnd gt { [ -01 stackEnd ] die } rep # Stack corrupted
+
+ { addr stackEnd lt } {
+ [
+ addr base16encode64 ": "
+ addr peekImm64 ==value
+ value base16encode64
+ value 105553116266496 ge value 123145302310912 lt and {
+ value peekImm32
+ value 4 add peekImm32 16777215 band 4294967296 mul
+ add 8 div ==length
+ 0 length 1 sub range {
+ 8 mul value add ==heapAddr
+ "\n "
+ heapAddr base16encode64
+ ": "
+ # the perl interpreter does not like full 64bit numbers and converts them into floats
+ heapAddr 4 add peekImm32 _ ==heapValueB base16encode32
+ heapAddr peekImm32 _ ==heapValueA base16encode32
+ " "
+ [ [ heapValueA heapValueB ] { 4 { _ 256 mod -01 256 div } rep -- } each ] ASCII * 8 dearray
+ } each
+ } rep
+ "\n"
+ ] |cat fold sys .out .writestr
+ addr 8 add =addr
+ } loop
+ "^^^^^^^^^^^^^^^^^^\n" sys .out .writestr
+ }
+ > -- /stackDump deff
> /assemblerLibrary defv
# vim: syn=elymas
diff --git a/compiler/elymasGlobal.ey b/compiler/elymasGlobal.ey
index b5d3ab5..64b2659 100644
--- a/compiler/elymasGlobal.ey
+++ b/compiler/elymasGlobal.ey
@@ -35,46 +35,9 @@
] :execute
} /TOKINT
- { .value strToUTF8Bytes _ =*v len _ ==exactLength
- 1 sub 8 div 4 add 8 mul ==memoryLength
+ { .value ::constStringCode :execute } /TOKSTR
- memoryLength 2147483648 lt assert
-
- [
- # allocate string
- memoryLength /rdi :movqImmReg
- ::internalAllocate /rax :movqImmReg
- /rax :callqReg
-
- # push string address on program stack
- /rax :pushqReg
-
- # set type
- 7 /rax :addqImm8Reg
- %10 /rax :orbImmMem64
-
- # clear hash value
- 1 /rax :addqImm8Reg
- /rdx /rdx :xorqRegReg
- /rdx /rax :movqRegMem
-
- # load exact length
- 8 /rax :addqImm8Reg
- exactLength /rdx :movqImmReg
- /rdx /rax :movqRegMem
-
- # load string contents
- 0 exactLength 8 div range { 8 mul ==i
- 8 /rax :addqImm8Reg
- /rdx :movqImmOOBReg i _ 7 add range v 8 dearray
- /rdx /rax :movqRegMem
- } each
- ]
- } /TOKSTRcode deff
-
- { TOKSTRcode :execute } /TOKSTR
-
- { TOKSTRcode
+ { .value ::constStringCode
[
# scope resolution
::currentScope /rdi :movqImmReg
@@ -85,11 +48,11 @@
/rax :pushqReg
/rdx /rdx :testqRegReg
- /inactive :labelRel8 /jzRel8
+ /inactive :jzLbl8
::ey* /rax :movqImmReg
/rax :callqReg
/inactive :label
- ] :labelResolve :execute
+ ] :labelResolve cat :execute
} /TOKID
> -- 3 |defv rep
@@ -128,7 +91,7 @@
4096 input .readstr cat
_ "" streq not
} {
- { _ "([^\\n]*)\\n(.*)" regex } { -102 -- tokenize { _ .handle assembler .stackDump } each } loop
+ { _ "([^\\n]*)\\n(.*)" regex } { -102 -- tokenize { _ .handle assemblerLibrary .stackDump } each } loop
} loop
} /executeFile deff