aboutsummaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorDrahflow <drahflow@gmx.de>2013-01-22 17:26:14 +0100
committerDrahflow <drahflow@gmx.de>2013-01-22 17:26:14 +0100
commit38c6689e33361193d3791a6fc6052824208c9cf7 (patch)
treea88cba212c663750240328eaadf3c1c6be82937d /compiler
parent7c0bcd61637a6101edf9a424ab4c369502378752 (diff)
= now working
Diffstat (limited to 'compiler')
-rw-r--r--compiler/elymasAsm.ey21
-rw-r--r--compiler/elymasAsmLib.ey171
2 files changed, 180 insertions, 12 deletions
diff --git a/compiler/elymasAsm.ey b/compiler/elymasAsm.ey
index 3f658d9..78d716b 100644
--- a/compiler/elymasAsm.ey
+++ b/compiler/elymasAsm.ey
@@ -436,6 +436,19 @@
%75 /jnz defJmpRel8
%74 /jz defJmpRel8
+ { ==reg ==mem ==idx ==scale ==disp
+ reg bit32assert
+ mem bit64assert
+ idx bit64assert
+ disp 128 lt assert
+
+ 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
+
{ ==reg ==mem ==disp
reg bit64assert
mem bit64assert
@@ -650,6 +663,14 @@
reg mem modrm00
} /movzxMem8Reg64 deff
+ { ==reg
+ reg bit64assert
+
+ 1 /none /none reg rex
+ %F7
+ /four reg modrm11
+ } /mulqReg deff
+
{ ==mem ==i
mem bit64assert
i 256 lt assert
diff --git a/compiler/elymasAsmLib.ey b/compiler/elymasAsmLib.ey
index fb1a487..9e59044 100644
--- a/compiler/elymasAsmLib.ey
+++ b/compiler/elymasAsmLib.ey
@@ -53,6 +53,8 @@
"unresolved name: " toErrString ==errUnresolvedName
"neither string nor array in len" toErrString ==errNeitherStringNorArrayInLen
"not an executable thing" toErrString ==errNotExecutable
+ "neither string nor array in cat" toErrString ==errNeitherStringNorArrayInCat
+ "type mismatch within cat" toErrString ==errMismatchInCat
> { defv }' allocateOffsetStruct
{ _ =*array len _ 4 div ==largeMoves
@@ -159,6 +161,7 @@
# rdx <- 0 if element is passive
# 1 if element is active
# 2 if element is quote-active
+ # rcx <- address of entry (i.e. where rdx was loaded from)
[
@retryWithParent
@@ -205,22 +208,24 @@
16 /rdx :subqImm8Reg # substract name table header size
/rdx :shrq1Reg # divide by 2 to get offset within scope
- # rdx == entry index * 8 in scope
+ /rdx /rcx :movqRegReg
+ # rcx == 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
+ 32 /rcx :addqImm8Reg # add scope header size
+ /ecx /rdi :cmplRegMem # TODO this fails for > 4 GB scopes
/inDataArea :jaLbl8
- /rdi /edx :sublMemReg # substract scope length
+ /rdi /ecx :sublMemReg # substract scope length
24 /rdi /rdi :movqMemDisp8Reg # load extension area pointer
/rdi /rdi :testqRegReg
/outsideExtensionArea :jzLbl8
- 8 /rdx :addqImm8Reg # add extension area header length
+ 8 /rcx :addqImm8Reg # add extension area header length
@inDataArea
- /rdx /rdi /rdx :movqMemIndexReg # load entry pointer
+ /rcx /rdi /rdx :movqMemIndexReg # load entry pointer
/rax /rdx :xchgqRegReg
+ /rdi /rcx :addqRegReg
:retn
@outsideExtensionArea
@@ -390,24 +395,37 @@
] /ey/ defv
# resolve in scope but never execute
+ # 0 -> name to resolve
+ # 0 <- whatever the name resolved to
[
/rcx :popqReg
- /rax :popqReg
+ /rbx :popqReg
/rcx :pushqReg
- /rax :pushqReg
# scope resolution
currentScope /rdi :movqImmReg
/rdi /rdi :movqMemReg
- /rsi :popqReg
+ /rbx /rsi :movqRegReg
internalResolve /rax :movqImmReg
/rax :callqReg
+ /rax /rax :testqRegReg
+ /found :jnzLbl8
+
+ errUnresolvedName /rdi :movqImmReg
+ internalDumpErrorString /rax :movqImmReg
+ /rax :callqReg
+ /rbx /rdi :movqRegReg
+ internalDumpErrorString /rax :movqImmReg
+ /rax :callqReg
+ :ud2
+
+ @found
/rcx :popqReg
/rax :pushqReg
/rcx :pushqReg
:retn
- ] /ey| defv
+ ] :labelResolve /ey| defv
# arithmetic functions on ints
[ /rcx /rdx :addqRegReg ] makeArith /eyadd defv
@@ -429,6 +447,13 @@
/rsi /rdx :movqRegReg
/rdi /rdx :cmovaqRegReg
] makeArith /eyge defv
+ [
+ /rax :pushqReg
+ /rcx /rax :movqRegReg
+ /rdx :mulqReg
+ /rax /rdx :movqRegReg
+ /rax :popqReg
+ ] makeArith /eymul defv
{ ==activation
# create a new entry in the current scope for the given name
@@ -576,6 +601,37 @@
1 -101* /eydeff defv
2 -01* /eydefq defv
+ # assign to a scope variable
+ # 0 -> name to assign to
+ # 1 -> value to assign
+ # does not change the default activation mode
+ [
+ /rbx :popqReg
+
+ currentScope /rdi :movqImmReg
+ /rdi /rdi :movqMemReg
+ /rsi :popqReg
+ internalResolve /rax :movqImmReg
+ /rax :callqReg
+
+ # rax == resolved value
+ # rcx == address of the value just resolved
+
+ /rax /rax :testqRegReg
+ /found :jnzLbl8
+
+ errUnresolvedName /rdi :movqImmReg
+ internalDumpErrorString /rax :movqImmReg
+ /rax :callqReg
+ :ud2
+
+ @found
+ /rcx :popqMem
+
+ /rbx :pushqReg
+ :retn
+ ] :labelResolve /ey= defv
+
# execute top stack element
# 0 -> function to execute
[
@@ -765,6 +821,82 @@
:retn
] :labelResolve /eylen defv
+ # concatenate two arrays or strings
+ # 0 -> second part of new array / string
+ # 1 -> first part of new array / string
+ # 0 <- concatenated array / string
+ [
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem
+
+ /rax :popqReg
+ 7 /rax /cl :movbMemDisp8Reg
+ %F0 /cl :andbImmReg
+ %70 /cl :cmpbImmReg
+ /arrayCat :jeLbl8
+ %10 /cl :cmpbImmReg
+ /stringCat :jeLbl8
+
+ errNeitherStringNorArrayInCat /rdi :movqImmReg
+ internalDumpErrorString /rax :movqImmReg
+ /rax :callqReg
+ :ud2
+
+ @arrayCat
+ /rbx :popqReg
+
+ 7 /rbx /cl :movbMemDisp8Reg
+ %F0 /cl :andbImmReg
+ %70 /cl :cmpbImmReg
+ /mismatch :jneLbl8
+
+ 16 /r15 :subqImm8Reg
+ /rax /r15 :movqRegMem
+ /rbx 8 /r15 :movqRegMemDisp8 # store
+
+ /rax /edi :movlMemReg
+ /rbx /edi :addlMemReg
+ 16 /rdi :subqImm8Reg # sum of lengths
+
+ internalAllocateArray /rax :movqImmReg
+ /rax :callqReg
+ /rax :pushqReg # result on stack
+
+ 8 /rax /rdi :leaqMemDisp8Reg
+
+ 8 /r15 /rbx :movqMemDisp8Reg
+ /rbx /ecx :movlMemReg
+ 8 /rbx /rsi :leaqMemDisp8Reg
+ 3 /rcx :shrqImm8Reg
+ /rcx :decqReg
+ :reprcx :movsq
+
+ /r15 /rbx :movqMemReg
+ /rbx /ecx :movlMemReg
+ 8 /rbx /rsi :leaqMemDisp8Reg
+ 3 /rcx :shrqImm8Reg
+ /rcx :decqReg
+ :reprcx :movsq
+
+ 16 /r15 :addqImm8Reg
+ /done :jmpLbl8
+
+ @stringCat
+ # TODO
+ :ud2
+
+ @mismatch
+ errMismatchInCat /rdi :movqImmReg
+ internalDumpErrorString /rax :movqImmReg
+ /rax :callqReg
+ :ud2
+
+ @done
+ /r15 :pushqMem
+ 8 /r15 :addqImm8Reg
+ :retn
+ ] :labelResolve /eycat defv
+
# create an array containing a continuous range of ints
# 0 -> last element included in range
# 1 -> first element included in range
@@ -827,14 +959,29 @@
# create a new scope capturing the current one
[
+ currentScope /rbx :movqImmReg
+
INITIALSCOPESIZE /rdi :movqImmReg
- currentScope /rsi :movqImmReg
- /rsi /rsi :movqMemReg
+ /rbx /rsi :movqMemReg
internalAllocateScope /rax :movqImmReg
/rax :callqReg
+ /rax /rbx :movqRegMem # switch to new scope
:retn
] /ey< defv
+
+ # push current scope onto stack
+ # switch current scope to its parent
+ [
+ /rbx :popqReg
+ currentScope /rax :movqImmReg
+ /rax :pushqMem
+ 16 /rax /rcx :movqMemDisp8Reg
+ /rcx /rax :movqRegMem
+ /rbx :pushqReg
+
+ :retn
+ ] /ey> defv
> _ ==globalFunctions { defv }' allocateOffsetStruct
{