diff options
| -rw-r--r-- | TODO | 1 | ||||
| -rw-r--r-- | compiler/elymasAsm.ey | 2 | ||||
| -rw-r--r-- | compiler/elymasAsmLib.ey | 18 | ||||
| -rw-r--r-- | compiler/elymasAsmOps.ey | 17 | ||||
| -rw-r--r-- | compiler/elymasGlobal.ey | 17 | ||||
| -rw-r--r-- | compiler/standardClient.ey | 14 | ||||
| -rw-r--r-- | doc/global.md | 43 | ||||
| -rw-r--r-- | elymas/lib/math.ey | 22 | ||||
| -rw-r--r-- | elymas/lib/sys/opt.ey | 4 | ||||
| -rw-r--r-- | interpreter/ElymasGlobal.pm | 2 |
10 files changed, 114 insertions, 26 deletions
@@ -7,6 +7,7 @@ * handle pipe creation * txt .consume .u sollte nicht negative Zahlen liefern * evtl. BigNums bauen und die Int-Funktionen entsprechend machen +* trigonometrics * consider polymorphic call-site caches instead of deffs_t_ / deffs? diff --git a/compiler/elymasAsm.ey b/compiler/elymasAsm.ey index 265ff95..ff57627 100644 --- a/compiler/elymasAsm.ey +++ b/compiler/elymasAsm.ey @@ -113,7 +113,7 @@ .base ==:quoteEncodingBufferObjects { ==opcodes - opcodes len 1 sub PAGESIZE div 1 add PAGESIZE mul alloc /codearea defv + opcodes len 1 sub PAGESIZE udiv 1 add PAGESIZE mul alloc /codearea defv sys .asm .|poke =*poke codearea .base opcodes { -101 poke 1 add } each -- codearea diff --git a/compiler/elymasAsmLib.ey b/compiler/elymasAsmLib.ey index 952e6b7..71763c6 100644 --- a/compiler/elymasAsmLib.ey +++ b/compiler/elymasAsmLib.ey @@ -26,7 +26,7 @@ struct values |cat fold ==data constantAllocEnd constantAllocBegin sub ==constantAllocFree data len constantAllocFree gt { - data len 1 sub :PAGESIZE div 1 add :PAGESIZE mul :alloc ==area + data len 1 sub :PAGESIZE udiv 1 add :PAGESIZE mul :alloc ==area area :globalAllocations .register area .base _ constantAllocEnd neq { area .base =constantAllocBegin } rep area .size add =constantAllocEnd @@ -43,7 +43,7 @@ %00 %00 %00 %00 %00 %00 %00 %00 str len :imm64 ] str strToUTF8Bytes cat - [ 8 str len 8 mod sub %00 rep ] cat + [ 8 str len 8 umod sub %00 rep ] cat } /toConstString deff [ ] ==stringHoles @@ -110,8 +110,8 @@ > { defv }' allocateOffsetStruct { ==register - { _ =*array len _ 4 div ==largeMoves - 4 mod ==smallMoves + { _ =*array len _ 4 udiv ==largeMoves + 4 umod ==smallMoves 0 ==i largeMoves { i _ 4 add =i @@ -382,7 +382,7 @@ 0 /rsi :cmpqImm8Mem /quoteEncodingBufferUnused :jzLbl8 - :STACKSIZE 8 sub 8 div /rcx :movqImmReg + :STACKSIZE 8 sub 8 udiv /rcx :movqImmReg @loopThroughEncodingBuffer /rsi /rdi :movqMemReg /markObject :callqLbl32 @@ -775,7 +775,7 @@ heapSize /rax :movqImmReg /rax /rdi :movqMemReg 7 /rdi :shrqImm8Reg - ALLOCCHUNKSIZE 128 div /rsi :movqImmReg + ALLOCCHUNKSIZE 128 udiv /rsi :movqImmReg /rsi /rdi :subqRegReg /rax :movqImmOOBReg BLOCKBASE /rax /rdi :addqRegReg @@ -784,7 +784,7 @@ heapSize /rax :movqImmReg /rax /rdi :movqMemReg 7 /rdi :shrqImm8Reg - ALLOCCHUNKSIZE 128 div /rsi :movqImmReg + ALLOCCHUNKSIZE 128 udiv /rsi :movqImmReg /rsi /rdi :subqRegReg /rax :movqImmOOBReg MARKBASE /rax /rdi :addqRegReg @@ -1304,7 +1304,7 @@ ] /unscopingFunctionFooter defv { strToUTF8Bytes _ =*v len _ ==exactLength - 1 sub 8 div 4 add 8 mul ==memoryLength + 1 sub 8 udiv 4 add 8 mul ==memoryLength memoryLength 2147483648 lt not { "constant string too long" die } rep @@ -1333,7 +1333,7 @@ exactLength 0 neq { # load string contents - 0 exactLength 1 sub 8 div 1 add range { 8 mul ==i + 0 exactLength 1 sub 8 udiv 1 add range { 8 mul ==i 8 /rax :addqImm8Reg /rdx :movqImmOOBReg i _ 8 add range v 8 dearray /rdx /rax :movqRegMem diff --git a/compiler/elymasAsmOps.ey b/compiler/elymasAsmOps.ey index 64b80f2..3adba21 100644 --- a/compiler/elymasAsmOps.ey +++ b/compiler/elymasAsmOps.ey @@ -119,10 +119,10 @@ %07 base regno band add } /sib deff -{ 8 { _ 256 mod -01 256 div } rep -- } /imm64 deff # div / mod unsigned -{ _ 0 lt { 4294967296 add } rep 4294967295 band 4 { _ 256 mod -01 256 div } rep -- } /imm32 deff -{ _ 0 lt { 65536 add } rep 65535 band 2 { _ 256 mod -01 256 div } rep -- } /imm16 deff -{ _ 0 lt { 256 add } rep 255 band } /imm8 deff +{ 8 { _ 256 umod -01 256 udiv } rep -- } /imm64 deff # div / mod unsigned +{ _ 0 lt { 4294967296 add } rep 4294967295 band 4 { _ 256 umod -01 256 udiv } rep -- } /imm32 deff +{ _ 0 lt { 65536 add } rep 65535 band 2 { _ 256 umod -01 256 udiv } rep -- } /imm16 deff +{ _ 0 lt { 256 add } rep 255 band } /imm8 deff { %66 } /width16 deff @@ -801,6 +801,15 @@ memoryAddressingVariants keys { ==variant memoryAddressingVariants variant . =*p { parse ==mem mem .base regno %07 gt mem .idx regno %07 gt or { 0 /none mem .idx mem .base rex } rep + %DF + /seven mem .encode + } /fistp64 variant defOp +} each + +memoryAddressingVariants keys { ==variant memoryAddressingVariants variant . =*parse + { parse ==mem + mem .base regno %07 gt mem .idx regno %07 gt or + { 0 /none mem .idx mem .base rex } rep %DD /zero mem .encode } /fld64 variant defOp diff --git a/compiler/elymasGlobal.ey b/compiler/elymasGlobal.ey index 0ddc202..2363c6b 100644 --- a/compiler/elymasGlobal.ey +++ b/compiler/elymasGlobal.ey @@ -3446,13 +3446,28 @@ [ /rax :pushqReg /rdx /rax :movqRegReg - /rdx /rdx :xorqRegReg + :cqo /rcx :idivqReg /rax /rdx :movqRegReg /rax :popqReg ] [ :fdivp ] 0 makeFullArith /eydiv defv + [[ + /rax :pushqReg + /rdx /rax :movqRegReg + /rdx /rdx :xorqRegReg + /rcx :divqReg + /rax :popqReg + ]] [[ "umod" floatUnsupported ]] 0 makeFullArith /eyumod defv + [ + /rax :pushqReg + /rdx /rax :movqRegReg + /rdx /rdx :xorqRegReg + /rcx :divqReg + /rax /rdx :movqRegReg + /rax :popqReg + ]] [[ "udiv" floatUnsupported ]] 0 makeFullArith /eyudiv defv [[ /rcx /rcx :testqRegReg diff --git a/compiler/standardClient.ey b/compiler/standardClient.ey index 6df429c..b31011c 100644 --- a/compiler/standardClient.ey +++ b/compiler/standardClient.ey @@ -80,7 +80,7 @@ < 0 ==size [ maxSize { 0 }" rep ] =*get - maxSize 1 sub 8 div 1 add 8 mul str .alloc _ zero ==pcUsed + maxSize 1 sub 8 udiv 1 add 8 mul str .alloc _ zero ==pcUsed { # ==thread _ threadGetPC pcUsed bitTest { -- }" { @@ -898,8 +898,8 @@ sys .asm .intToFloat } each ] =*:FLOAT - { - [ -01 16 { _ 16 mod base16digits * -01 16 div } rep -- ] reverse str .fromArray + { _ 0 lt { neg "-" } { "" } ? * -01 + [ -01 16 { _ 16 umod base16digits * -01 16 udiv } rep -- ] reverse str .fromArray cat } /base16encode64 deffd { ==indent _ ==o @@ -985,13 +985,13 @@ 1 0 { strNumber * 48 sub [ 0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 10 11 12 13 14 15 ] * } -20*10* 16 mul add } "%" defq - { 8 { _ 256 mod -01 256 div } rep -- } /uint64 deffd - { _ 0 lt { 4294967296 add } rep 4294967295 band 4 { _ 256 mod -01 256 div } rep -- } /uint32 deffd - { _ 0 lt { 65536 add } rep 65535 band 2 { _ 256 mod -01 256 div } rep -- } /uint16 deffd + { 8 { _ 256 umod -01 256 udiv } rep -- } /uint64 deffd + { _ 0 lt { 4294967296 add } rep 4294967295 band 4 { _ 256 umod -01 256 udiv } rep -- } /uint32 deffd + { _ 0 lt { 65536 add } rep 65535 band 2 { _ 256 umod -01 256 udiv } rep -- } /uint16 deffd { _ 0 lt { 256 add } rep 255 band } /uint8 deffd { ==align ==value - align value align mod sub align mod + align value align umod sub align umod } /alignUpto deff sys .file ==out diff --git a/doc/global.md b/doc/global.md index b6d74b1..8880d5d 100644 --- a/doc/global.md +++ b/doc/global.md @@ -593,12 +593,51 @@ Multiplies two integers or floats. `div` ----- -Divides two integers or floats. The integer version truncates the result towards zero. +Divides two (signed) integers or floats. The integer version truncates the result towards zero. 5 2 div dump 0000000000000002 5 2 neg div dump - FFFFFFFFFFFFFFFE + -0000000000000002 + + +`mod` +----- + +Computes the remainder of a signed integer division. The result is always positive. + + 5 2 mod dump + 0000000000000001 + 5 neg 2 mod dump + 0000000000000001 + + +`udiv` +----- + +Divides two unsigned integers. Truncates the result towards zero. Use this only +if you need full 64bit unsigned integer arithmetic. + + 5 2 udiv dump + 0000000000000002 + 5 2 neg udiv dump + 0000000000000000 + 5 neg 2 udiv dump + 7FFFFFFFFFFFFFFD + + +`umod` +----- + +Computes the remainder of an unsigned integer division. The result is always +positive. Use this only if you need full 64bit unsigned integer arithmetic. + + 5 2 umod dump + 0000000000000001 + 5 neg 3 mod dump + 0000000000000001 + 5 neg 3 umod dump + 0000000000000002 `and` diff --git a/elymas/lib/math.ey b/elymas/lib/math.ey index db04c7b..cc9b288 100644 --- a/elymas/lib/math.ey +++ b/elymas/lib/math.ey @@ -24,4 +24,26 @@ } /base deff > /math defv +# FIXME: INTEGRATE +# # 0 -> float +# # 0 <- the int portion of the float, rounded towards zero +# [[ +# /rbx :popqReg +# +# # allocate result int +# ::internalAllocateInteger /rax :movqImmReg +# /rax :callqReg +# +# # actual conversion +# /rcx :popqReg +# 8 /rcx :fld64MemDisp8 +# 8 /rax :fistp64MemDisp8 +# +# # push int on program stack +# /rax :pushqReg +# +# /rbx :pushqReg +# :retn +# ]] /eytrunc defv + # vim: syn=elymas diff --git a/elymas/lib/sys/opt.ey b/elymas/lib/sys/opt.ey index 4229748..df3d210 100644 --- a/elymas/lib/sys/opt.ey +++ b/elymas/lib/sys/opt.ey @@ -891,7 +891,7 @@ /rsi /ecx :movlMemReg 3 /rcx :shrqImm8Reg /rcx :decqReg - /rdx /rdx :xorqRegReg + /rdx /rdx :xorqRegReg # FIXME: Is this correct? /rcx :divqReg 8 8 /rdx /rsi :pushqMemIndexScaleDisp8 ] emitOpcodes @@ -906,7 +906,7 @@ 8 /rax /rax :movqMemDisp8Reg 16 /rsi /rcx :movqMemDisp8Reg /rdx /rdx :xorqRegReg - /rcx :divqReg + /rcx :divqReg # FIXME: Is this correct? 24 1 /rdx /rsi /rbx :movzxMem8IndexScaleDisp8Reg64 63 /rbx :btsqImm8Reg /rbx :pushqReg diff --git a/interpreter/ElymasGlobal.pm b/interpreter/ElymasGlobal.pm index 61d32c4..4080661 100644 --- a/interpreter/ElymasGlobal.pm +++ b/interpreter/ElymasGlobal.pm @@ -778,6 +778,8 @@ installGlobal2IntFunction('sub', '$a - $b'); installGlobal2IntFunction('mul', '$a * $b'); installGlobal2IntFunction('div', 'int($a / $b)'); installGlobal2IntFunction('mod', '$a % $b'); +installGlobal2IntFunction('udiv', 'int($a / $b)'); # cheap compatibility hack +installGlobal2IntFunction('umod', '$a % $b'); # cheap compatibility hack installGlobal2IntFunction('and', '($a and $b)? 1: 0'); installGlobal2IntFunction('nand', '($a and $b)? 0: 1'); |
