github.com/cloudwego/frugal@v0.1.15/internal/atm/pgen/pgen_legacy_amd64.go (about)

     1  // +build !go1.17
     2  
     3  /*
     4   * Copyright 2022 ByteDance Inc.
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   *     http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package pgen
    20  
    21  import (
    22      `runtime`
    23  
    24      `github.com/cloudwego/iasm/x86_64`
    25      `github.com/cloudwego/frugal/internal/atm/hir`
    26      `github.com/cloudwego/frugal/internal/atm/rtx`
    27  )
    28  
    29  /** Stack Checking **/
    30  
    31  const (
    32      _M_memcpyargs  = 24
    33      _G_stackguard0 = 0x10
    34  )
    35  
    36  func (self *CodeGen) abiStackCheck(p *x86_64.Program, to *x86_64.Label, sp uintptr) {
    37      ctxt := self.ctxt
    38      size := ctxt.size() + int32(sp)
    39  
    40      /* get the current goroutine */
    41      switch runtime.GOOS {
    42          case "linux"  : p.MOVQ (Abs(-8), RCX).FS()
    43          case "darwin" : p.MOVQ (Abs(0x30), RCX).GS()
    44          default       : panic("unsupported operating system")
    45      }
    46  
    47      /* check the stack guard */
    48      p.LEAQ (Ptr(RSP, -size), RAX)
    49      p.CMPQ (Ptr(RCX, _G_stackguard0), RAX)
    50      p.JBE  (to)
    51  }
    52  
    53  /** Efficient Block Copy Algorithm **/
    54  
    55  func (self *CodeGen) abiBlockCopy(p *x86_64.Program, pd hir.PointerRegister, ps hir.PointerRegister, nb hir.GenericRegister) {
    56      rd := self.r(pd)
    57      rs := self.r(ps)
    58      rl := self.r(nb)
    59  
    60      /* save all the registers, if they will be clobbered */
    61      for _, lr := range self.ctxt.regs {
    62          if rr := self.r(lr); rtx.R_memmove[rr] {
    63              p.MOVQ(rr, self.ctxt.slot(lr))
    64          }
    65      }
    66  
    67      /* load the args and call the function */
    68      p.MOVQ(rd, Ptr(RSP, 0))
    69      p.MOVQ(rs, Ptr(RSP, 8))
    70      p.MOVQ(rl, Ptr(RSP, 16))
    71      p.MOVQ(uintptr(rtx.F_memmove), RDI)
    72      p.CALLQ(RDI)
    73  
    74      /* restore all the registers, if they were clobbered */
    75      for _, lr := range self.ctxt.regs {
    76          if rr := self.r(lr); rtx.R_memmove[rr] {
    77              p.MOVQ(self.ctxt.slot(lr), rr)
    78          }
    79      }
    80  }