diff options
| author | Drahflow <drahflow@gmx.de> | 2013-01-05 19:00:53 +0100 |
|---|---|---|
| committer | Drahflow <drahflow@gmx.de> | 2013-01-05 19:00:53 +0100 |
| commit | ebc7f37a48a157145cac7473ec3a63e7ce34cc35 (patch) | |
| tree | bbde89f34cf5daf0ce4e74e35f800d6b3c46c96c /compiler | |
| parent | 19d573cf7c6dd729289ef5151f15db51bcc79d91 (diff) | |
In progress: Scope resolution assembly
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/elymasAsm.ey | 121 | ||||
| -rw-r--r-- | compiler/elymasAsmLib.ey | 110 | ||||
| -rw-r--r-- | compiler/elymasGlobal.ey | 26 |
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 |
