aboutsummaryrefslogtreecommitdiff
path: root/compiler/elymasGlobalStr.ey
blob: 299d880177046f55d5f748f6e2e3bb0ece4b80a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<
  "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
      16 /rax :popqMemDisp8

      /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 postfix
    # TODO: correctly handly negative indices
    # 0 -> string to shorten
    # 1 -> position of string where to start the postfix
    # 0 <- the requested postfix of the string
    [[
      /rbx :popqReg

      /rax :popqReg
      /rcx :popqReg

      /rax :pushqReg

      16 /rax /rdi :movqMemDisp8Reg
      8 /rcx /rdi :subqMemDisp8Reg
      /rdi :pushqReg

      ::internalAllocateString /rax :movqImmReg
      /rax :callqReg

      /rcx :popqReg
      /rsi :popqReg
      /rax :pushqReg # store target string on stack

      16 /rsi /rdx :movqMemDisp8Reg
      /rcx /rdx :subqRegReg

      24 1 /rdx /rsi /rsi :leaqMemIndexScaleDisp8Reg
      24 /rax /rdi :leaqMemDisp8Reg
      :reprcx :movsb

      /rbx :pushqReg
      :retn
    ]] /eypostfix defv
  > _ ==globalFunctions { defv }' ::allocateOffsetStruct

  [
    globalFunctions keys eydeff { | }' createScopeEntries
    createScopeExtensionEntries
  ] :execute

  leaveSubScope
> --

# vim: syn=elymas