< "str" enterSubScope < # allocate an uninitialized string # 0 -> number of data bytes to allocate # 0 <- the string [[ /rbx :popqReg /rdi :popqReg /rdi :pushqReg 8 /rdi /rdi :movqMemDisp8Reg 24 /rdi :addqImm8Reg ::internalAllocate /rax :movqImmReg /rax :callqReg # set type %10 7 /rax :orbImmMemDisp8 # clear hash value /rdx /rdx :xorqRegReg /rdx 8 /rax :movqRegMemDisp8 # set exact length /rdi :popqReg 8 /rdi /rdi :movqMemDisp8Reg /rdi 16 /rax :movqRegMemDisp8 /rax :pushqReg /rbx :pushqReg :retn ]] /eyalloc defv # reduce exact string length in place # 0 -> string to shorten # 1 -> length of prefix # 0 <- the same string (but now with exact length field overwritten) # this effectively creates a prefix of the string [[ /rbx :popqReg /rax :popqReg /rcx :popqReg 8 /rcx /rcx :movqMemDisp8Reg 16 /rax /rcx :cmpqMemDisp8Reg /ok :jbeLbl8 "prefix length above string length in inplacePrefix" ::outputError :ud2 @ok /rcx 16 /rax :movqRegMemDisp8 /rcx /rcx :xorqRegReg /rcx 8 /rax :movqRegMemDisp8 # reset hash value /rax :pushqReg /rbx :pushqReg :retn ]] /eyinplacePrefix defv # calculate a string infix # 0 -> string to shorten # 1 -> first position after the infix # 2 -> first position in the infix [[ /rbx :popqReg /rcx :popqReg # rcx == string 16 /rcx /rbp :movqMemDisp8Reg /rdi :popqReg 8 /rdi /rdi :movqMemDisp8Reg 0 /rdi :cmpqImm8Reg /positiveEndOffset :jgeLbl8 /rbp /rdi :addqRegReg @positiveEndOffset /rsi :popqReg 8 /rsi /rsi :movqMemDisp8Reg 0 /rsi :cmpqImm8Reg /positiveStartOffset :jgeLbl8 /rbp /rsi :addqRegReg @positiveStartOffset # rdi == end offset # rsi == start offset /rcx :pushqReg /rsi :pushqReg /rsi /rdi :subqRegReg /negativeLengthInfix :jsLbl8 @negativeLengthInfixFixed /rdi :pushqReg ::internalAllocateString /rax :movqImmReg /rax :callqReg /rcx :popqReg # rcx == count of bytes to copy /rsi :popqReg # rsi == start offset /rdx :popqReg # rdx == source string /rax :pushqReg :cld /rcx /rcx :testqRegReg 24 1 /rsi /rdx /rsi :leaqMemIndexScaleDisp8Reg 24 /rax /rdi :leaqMemDisp8Reg :reprcx :movsb /rbx :pushqReg :retn @negativeLengthInfix /rdi /rdi :xorqRegReg /negativeLengthInfixFixed :jmpLbl8 ]] /eyinfix defv # calculate a string prefix # 0 -> string to shorten # 1 -> first position after the prefix [[ /rbx :popqReg /rcx :popqReg # rcx == string 16 /rcx /rbp :movqMemDisp8Reg /rdi :popqReg 8 /rdi /rdi :movqMemDisp8Reg 0 /rdi :cmpqImm8Reg /positiveEndOffset :jgeLbl8 /rbp /rdi :addqRegReg @positiveEndOffset /rsi /rsi :xorqRegReg # rdi == end offset # rsi == start offset /rcx :pushqReg /rsi :pushqReg /rsi /rdi :subqRegReg /negativeLengthInfix :jsLbl8 @negativeLengthInfixFixed /rdi :pushqReg ::internalAllocateString /rax :movqImmReg /rax :callqReg /rcx :popqReg # rcx == count of bytes to copy /rsi :popqReg # rsi == start offset /rdx :popqReg # rdx == source string /rax :pushqReg :cld /rcx /rcx :testqRegReg 24 1 /rsi /rdx /rsi :leaqMemIndexScaleDisp8Reg 24 /rax /rdi :leaqMemDisp8Reg :reprcx :movsb /rbx :pushqReg :retn @negativeLengthInfix /rdi /rdi :xorqRegReg /negativeLengthInfixFixed :jmpLbl8 ]] /eyprefix defv # calculate a string postfix # 0 -> string to shorten # 1 -> position of string where to start the postfix # 0 <- the requested postfix of the string [[ /rbx :popqReg /rcx :popqReg # rcx == string 16 /rcx /rbp :movqMemDisp8Reg /rbp /rdi :movqRegReg /rsi :popqReg 8 /rsi /rsi :movqMemDisp8Reg 0 /rsi :cmpqImm8Reg /positiveStartOffset :jgeLbl8 /rbp /rsi :addqRegReg @positiveStartOffset # rdi == end offset # rsi == start offset /rcx :pushqReg /rsi :pushqReg /rsi /rdi :subqRegReg /negativeLengthInfix :jsLbl8 @negativeLengthInfixFixed /rdi :pushqReg ::internalAllocateString /rax :movqImmReg /rax :callqReg /rcx :popqReg # rcx == count of bytes to copy /rsi :popqReg # rsi == start offset /rdx :popqReg # rdx == source string /rax :pushqReg :cld /rcx /rcx :testqRegReg 24 1 /rsi /rdx /rsi :leaqMemIndexScaleDisp8Reg 24 /rax /rdi :leaqMemDisp8Reg :reprcx :movsb /rbx :pushqReg :retn @negativeLengthInfix /rdi /rdi :xorqRegReg /negativeLengthInfixFixed :jmpLbl8 ]] /eypostfix defv # produce a string from an integer array specifying its bytes # 0 -> array of integers # 0 <- the same bytes as a string [[ /rbx :popqReg /rsi :popqReg /rsi :pushqReg /rsi /edi :movlMemReg # load array length 3 /rdi :shrqImm8Reg /rdi :decqReg /rdi :pushqReg ::internalAllocateString /rax :movqImmReg /rax :callqReg /rcx :popqReg # number of characters to copy /rsi :popqReg 8 /rsi :addqImm8Reg # move rsi to first array entry /rax :pushqReg # store target string on stack 24 /rax :addqImm8Reg # move rax to first string byte @copyByte /rsi /rdx :movqMemReg # load object pointer 8 /rdx /rdx :movqMemDisp8Reg # load integer value /dl /rax :movbRegMem 8 /rsi :addqImm8Reg /rax :incqReg /copyByte :loopLbl8 /rbx :pushqReg :retn ]] /eyfromArray defv > _ ==globalFunctions { defv }' ::allocateOffsetStruct [ globalFunctions keys eydeff { | }' createScopeEntries createScopeExtensionEntries ] :execute leaveSubScope > -- # vim: syn=elymas