aboutsummaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorDrahflow <drahflow@gmx.de>2013-01-05 19:00:53 +0100
committerDrahflow <drahflow@gmx.de>2013-01-05 19:00:53 +0100
commitebc7f37a48a157145cac7473ec3a63e7ce34cc35 (patch)
treebbde89f34cf5daf0ce4e74e35f800d6b3c46c96c /compiler
parent19d573cf7c6dd729289ef5151f15db51bcc79d91 (diff)
In progress: Scope resolution assembly
Diffstat (limited to 'compiler')
-rw-r--r--compiler/elymasAsm.ey121
-rw-r--r--compiler/elymasAsmLib.ey110
-rw-r--r--compiler/elymasGlobal.ey26
3 files changed, 235 insertions, 22 deletions
diff --git a/compiler/elymasAsm.ey b/compiler/elymasAsm.ey
index f11f950..4015b04 100644
--- a/compiler/elymasAsm.ey
+++ b/compiler/elymasAsm.ey
@@ -56,6 +56,22 @@
} /modrm00 deff
{ =mem =reg
+ mem [ /spl /sp /esp /rsp ] streq any not assert
+
+ %40
+ mem regno %07 band add
+ reg regno 8 mul %38 band add
+ } /modrm01 deff
+
+ { =mem =reg
+ mem [ /spl /sp /esp /rsp ] streq any not assert
+
+ %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
@@ -77,6 +93,17 @@
i imm8
} /addqImm8Reg deff
+ { ==reg ==mem ==disp
+ reg bit64 assert
+ mem bit64 assert
+ disp 128 lt assert
+
+ 1 reg /none mem rex
+ %03
+ reg mem modrm01
+ disp imm8
+ } /addqMemDisp8Reg deff
+
{ ==dst ==src
dst bit64 assert
src bit64 assert
@@ -94,6 +121,15 @@
/two reg modrm11
} /callqReg deff
+ {
+ %A6
+ } /cmpsb deff
+
+ {
+ 1 /none /none /none rex
+ %A7
+ } /cmpsq deff
+
{ ==dst ==src
dst bit64 assert
src bit64 assert
@@ -117,6 +153,27 @@
offset imm8
} /jleRel8 deff
+ { ==offset
+ offset 128 lt assert
+
+ %73
+ offset imm8
+ } /jnbRel8 deff
+
+ { ==offset
+ offset 128 lt assert
+
+ %75
+ offset imm8
+ } /jnzRel8 deff
+
+ { ==offset
+ offset 128 lt assert
+
+ %74
+ offset imm8
+ } /jzRel8 deff
+
{ ==reg ==i
reg bit64 assert
@@ -132,6 +189,17 @@
%B8 reg regno %07 band add
} /movqImmOOBReg deff
+ { ==reg ==mem ==disp
+ reg bit64 assert
+ mem bit64 assert
+ disp 128 lt assert
+
+ 1 reg /none mem rex
+ %8B
+ reg mem modrm01
+ disp imm8
+ } /movqMemDisp8Reg deff
+
{ ==reg ==mem
reg bit64 assert
mem bit64 assert
@@ -184,6 +252,10 @@
} /pushqImm32 deff
{
+ %F3
+ } /repz deff
+
+ {
%C3
} /retn deff
@@ -200,6 +272,24 @@
%0F %05
} /syscall deff
+ { ==dst ==src
+ dst bit64 assert
+ src bit64 assert
+
+ 1 src /none dst rex
+ %85
+ src dst modrm11
+ } /testqRegReg deff
+
+ { ==mem ==reg
+ reg bit64 assert
+ mem bit64 assert
+
+ 1 reg /none mem rex
+ %87
+ reg mem modrm00
+ } /xchgqRegMem deff
+
{ ==reg ==mem
reg bit64 assert
mem bit64 assert
@@ -227,6 +317,27 @@
src dst modrm11
} /xorqRegReg deff
+ # label handling
+ < { defv }' /put deff > ==labels
+ < { defv }' /put deff > ==labelHoles
+
+ { ==l
+ ] _ len l labels .put [ -011 len dearray
+ } /label deff
+
+ { ==l
+ ] _ len ==offset
+ { offset labels .l sub imm8 offset -102 =[] } l labelHoles .put
+ [ -011 len dearray %00
+ } /labelRel8 deff
+
+ { ==opcodes
+ labelHoles { opcodes * } each
+
+ < { defv }' /put deff > =labels
+ < { defv }' /put deff > =labelHoles
+ } /labelResolve deff
+
# data manipulation functions
{ # ==addr
[ -01 8 { _ sys .asm .peek -01 1 add } rep -- ] reverse { -01 256 mul add } fold
@@ -239,8 +350,6 @@
# global stack layout
# 0 - STACKSTART : global variables
# %0 : current stack pointer
- # %8 : current scope
- # %10 : currently quoted
# STACKSTART - ...: real stack
STACKSIZE sys .asm .alloc ==mainStack
<
@@ -321,14 +430,10 @@
[
/rbx pushqReg
stack /rbx movqImmReg
- /rbx /rsp xorqMemReg
- /rsp /rbx xorqRegMem
- /rbx /rsp xorqMemReg
+ /rsp /rbx xchgqRegMem
] opcodes [
stack /rbx movqImmReg
- /rbx /rsp xorqMemReg
- /rsp /rbx xorqRegMem
- /rbx /rsp xorqMemReg
+ /rsp /rbx xchgqRegMem
/rbx popqReg
retn
] cat cat =opcodes
diff --git a/compiler/elymasAsmLib.ey b/compiler/elymasAsmLib.ey
index 341c07a..71321d2 100644
--- a/compiler/elymasAsmLib.ey
+++ b/compiler/elymasAsmLib.ey
@@ -30,16 +30,19 @@
# next free byte at end of heap
[ %00 %00 %00 %00 %00 %60 %00 %00 ] ==unusedHeapStart
+
+ # current parser scope
+ [ %00 %00 %00 %00 %00 %00 %00 %00 ] ==currentScope
> { defv }' allocateOffsetStruct
- # internal functions, ABI follows SysV standards
-
<
- # allocate a chunk of memory
- # rdi -> size of chunk in bytes
- # rax <- address of allocated chunk
- # chunk will have GC length header initialized correctly
- # FIXME put a real allocator here
+ # internal functions, ABI follows SysV standards
+
+ # allocate a chunk of memory
+ # rdi -> size of chunk in bytes
+ # rax <- address of allocated chunk
+ # chunk will have GC length header initialized correctly
+ # FIXME put a real allocator here
[
/rbx :pushqReg
/rdi :pushqReg
@@ -75,6 +78,99 @@
/rbx :popqReg
:retn
] /internalAllocate defv
+
+ # compare two strings
+ # rdi -> address of first string
+ # rsi -> address of second string
+ # rax <- 1 if both strings are equal
+ [
+ /rax /rax :xorqRegReg
+ :cmpsq # ignore memory length header
+ :cmpsq # ignore hash
+ /rsi /rdx :movqMemReg # load exact length
+ :cmpsq # same exact length
+ /fail :labelRel8 :jnzRel8
+ /rdx /rcx :movqRegReg
+ :repz :cmpsb
+ /fail :labelRel8 :jnzRel8
+ /rax :incqReg
+ /fail :label
+ ] :labelResolve /internalStringEqualsCode defv
+
+ internalStringEqualsCode [
+ :retn
+ ] cat /internalStringEquals defv
+
+ # resolve element from scope
+ # rdi -> address of scope on the heap
+ # rsi -> address of element name on the heap
+ # rax <- address of element on the heap (0 if nonexistant)
+ # rdx <- 0 if element is passive
+ # 1 if element is active
+ # 2 if element is quote-active
+ [
+ 8 /rdi /rcx :movqMemDisp8Reg # load name table
+ /rcx /rdx :movqRegReg
+ 16 /rdx :addqImm8Reg # rdx will iterate over entries
+ 8 /rcx /rcx :addqMemDisp8Reg # compute name table effective end
+
+ /loop :label
+ /rdx /rcx :cmpqRegReg
+ /end :labelRel8 :jnbRel8
+ # TODO this is ridiculous
+ /rdi :pushqReg
+ /rsi :pushqReg
+ /rdx :pushqReg
+ /rcx :pushqReg
+ /rdx /rdi :movqMemReg
+ ] internalStringEqualsCode [
+ /rcx :popReg
+ /rdx :popReg
+ /rsi :popReg
+ /rdi :popReg
+
+ /rax /rax :testqRegReg
+ /found :labelRel8 :jnzRel8
+
+ 16 /rdx :addqImm8Reg
+ /loop :labelRel8 :jmpRel8
+ /end :label
+
+ # not found at all, retry with parent
+ /rax /rax :xorqRegReg
+ /rdx /rdx :xorqRegReg
+ :retn
+
+ /found :label
+ 8 /rdx /rax :movqMemDisp8Reg # load default activation
+ 8 /rdi /rdx :subqMemDisp8Reg # substract name table start
+ 16 /rdx :subqImm8Reg # substract name table header size
+ /rdx :shrq1Reg # divide by 2 to get offset within scope
+
+ # rdx == entry index * 8 in scope
+ # rax == entry default activation
+
+ 32 /rdx :addqImm8Reg # add scope header size
+ /edx /rdi :cmplRegMem # TODO this fails for > 4 GB scopes
+ /inDataArea :labelRel8 :jbRel8
+
+ /rdi /edx :sublMemReg # substract scope length
+ 8 /rdx :addqImm8Reg # add extension area header length
+ 24 /rdi /rdi :movqMemDisp8Reg # load extension area pointer
+
+ /inDataArea :label
+ /rdx /rdi /rdx :movqMemIndexReg # load entry pointer
+ /rax /rdx :xchgqRegReg
+ :retn
+ ] cat cat :labelResolve /internalResolve defv
+
+ # elymas functions, stack based ABI
+
+ # execute top element of the stack
+ [
+# FIXME
+ :retn
+ ] /ey* defv
> { defv }' allocateOffsetStruct
> /assemblerLibrary defv
diff --git a/compiler/elymasGlobal.ey b/compiler/elymasGlobal.ey
index 6a92f50..d83ebc7 100644
--- a/compiler/elymasGlobal.ey
+++ b/compiler/elymasGlobal.ey
@@ -69,14 +69,26 @@
/rdx :movqImmOOBReg i _ 7 add range v 8 dearray
/rdx /rax :movqRegMem
} each
- ] :execute
- } /TOKSTR -1010 deff
+ ]
+ } /TOKSTRcode deff
+
+ { TOKSTRcode :execute } /TOKSTR
+
+ { TOKSTRcode
+ [
+ # scope resolution
+ ::currentScope /rdi :movqImmReg
+ /rsi :popqReg
+ ::internalResolve /rax :movqImmReg
+ /rax :callqReg
+ /rax :pushqReg
- { ==token
- # string value
- token TOKSTR
- # scope resolution
- # FIXME
+ /rdx /rdx :testqRegReg
+ [
+ ::ey* /rax :movqImmReg
+ /rax :callqReg
+ ] |len { :jzRel8 } -21*0*221* dearray
+ ] cat :execute
} /TOKID
> -- 3 |defv rep