Subversion Repositories Kolibri OS

Rev

Rev 2434 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ; Macroinstructions for defining and calling procedures
  2.  
  3. macro stdcall proc,[arg]                ; directly call STDCALL procedure
  4.  { common
  5.     if ~ arg eq
  6.    reverse
  7.         pushd   arg
  8.    common
  9.     end if
  10.         call    proc }
  11.  
  12. macro invoke proc,[arg]                 ; indirectly call STDCALL procedure
  13.  { common
  14.     if ~ arg eq
  15.    reverse
  16.         pushd   arg
  17.    common
  18.     end if
  19.         call    [proc] }
  20.  
  21. macro ccall proc,[arg]                  ; directly call CDECL procedure
  22.  { common
  23.     size@ccall = 0
  24.     if ~ arg eq
  25.    reverse
  26.         pushd   arg
  27.     size@ccall = size@ccall+4
  28.    common
  29.     end if
  30.         call    proc
  31.     if size@ccall
  32.         add     esp, size@ccall
  33.     end if }
  34.  
  35. macro cinvoke proc,[arg]                ; indirectly call CDECL procedure
  36.  { common
  37.     size@ccall = 0
  38.     if ~ arg eq
  39.    reverse
  40.         pushd   arg
  41.     size@ccall = size@ccall+4
  42.    common
  43.     end if
  44.         call    [proc]
  45.     if size@ccall
  46.         add     esp, size@ccall
  47.     end if }
  48.  
  49. macro proc [args]                       ; define procedure
  50.  { common
  51.     match name params, args>
  52.     \{ define@proc name,<params \} }
  53.  
  54. prologue@proc equ prologuedef
  55.  
  56. macro prologuedef procname,flag,parmbytes,localbytes,reglist
  57.  { if parmbytes | localbytes
  58.         push    ebp
  59.         mov     ebp, esp
  60.     if localbytes
  61.         sub     esp, localbytes
  62.     end if
  63.    end if
  64.    irps reg, reglist \{ push reg \} }
  65.  
  66. epilogue@proc equ epiloguedef
  67.  
  68. macro epiloguedef procname,flag,parmbytes,localbytes,reglist
  69.  { irps reg, reglist \{ reverse pop reg \}
  70.    if parmbytes | localbytes
  71.         leave
  72.    end if
  73.    if flag and 10000b
  74.         retn
  75.    else
  76.         retn    parmbytes
  77.    end if }
  78.  
  79. macro define@proc name,statement
  80.  { local params,flag,regs,parmbytes,localbytes,current
  81.    if used name
  82.    name:
  83.    match =stdcall args, statement \{ params equ args
  84.                                      flag = 11b \}
  85.    match =stdcall, statement \{ params equ
  86.                                 flag = 11b \}
  87.    match =c args, statement \{ params equ args
  88.                                flag = 10001b \}
  89.    match =c, statement \{ params equ
  90.                           flag = 10001b \}
  91.    match =params, params \{ params equ statement
  92.                             flag = 0 \}
  93.    virtual at ebp+8
  94.    match =uses reglist=,args, params \{ regs equ reglist
  95.                                         params equ args \}
  96.    match =regs =uses reglist, regs params \{ regs equ reglist
  97.                                              params equ \}
  98.    match =regs, regs \{ regs equ \}
  99.    match =,args, params \{ defargs@proc args \}
  100.    match =args@proc args, args@proc params \{ defargs@proc args \}
  101.    parmbytes = $ - (ebp+8)
  102.    end virtual
  103.    name # % = parmbytes/4
  104.    all@vars equ
  105.    current = 0
  106.    match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
  107.    macro locals
  108.    \{ virtual at ebp-localbytes+current
  109.       macro label . \\{ deflocal@proc .,:, \\}
  110.       struc db [val] \\{ \common deflocal@proc .,db,val \\}
  111.       struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
  112.       struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
  113.       struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
  114.       struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
  115.       struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
  116.       struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
  117.       struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
  118.       struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
  119.       struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
  120.       struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
  121.       struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
  122.    macro endl
  123.    \{ purge label
  124.       restruc db,dw,dp,dd,dt,dq
  125.       restruc rb,rw,rp,rd,rt,rq
  126.       restruc byte,word,dword,pword,tword,qword
  127.       current = $-(ebp-localbytes)
  128.       end virtual \}
  129.    macro ret operand
  130.    \{ match any, operand \\{ retn operand \\}
  131.       match , operand \\{ match epilogue:reglist, epilogue@proc:<regs>
  132.                           \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
  133.    macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2
  134.                         end if \} }
  135.  
  136. macro defargs@proc [arg]
  137.  { common
  138.     if ~ arg eq
  139.    forward
  140.      local ..arg,current@arg
  141.      match argname:type, arg
  142.       \{ current@arg equ argname
  143.          label ..arg type
  144.          argname equ ..arg
  145.          if dqword eq type
  146.            dd ?,?,?,?
  147.          else if tbyte eq type
  148.            dd ?,?,?
  149.          else if qword eq type | pword eq type
  150.            dd ?,?
  151.          else
  152.            dd ?
  153.          end if \}
  154.      match =current@arg,current@arg
  155.       \{ current@arg equ arg
  156.          arg equ ..arg
  157.          ..arg dd ? \}
  158.    common
  159.      args@proc equ current@arg
  160.    forward
  161.      restore current@arg
  162.    common
  163.     end if }
  164.  
  165. macro deflocal@proc name,def,[val]
  166.  { common
  167.     match vars, all@vars \{ all@vars equ all@vars, \}
  168.     all@vars equ all@vars name
  169.    forward
  170.     local ..var,..tmp
  171.     ..var def val
  172.     match =?, val \{ ..tmp equ \}
  173.     match any =dup (=?), val \{ ..tmp equ \}
  174.     match tmp : value, ..tmp : val
  175.      \{ tmp: end virtual
  176.         initlocal@proc ..var,def value
  177.         virtual at tmp\}
  178.    common
  179.     match first rest, ..var, \{ name equ first \} }
  180.  
  181. macro initlocal@proc name,def
  182.  { virtual at name
  183.     def
  184.     size@initlocal = $ - name
  185.    end virtual
  186.    position@initlocal = 0
  187.    while size@initlocal > position@initlocal
  188.     virtual at name
  189.      def
  190.      if size@initlocal - position@initlocal < 2
  191.       current@initlocal = 1
  192.       load byte@initlocal byte from name+position@initlocal
  193.      else if size@initlocal - position@initlocal < 4
  194.       current@initlocal = 2
  195.       load word@initlocal word from name+position@initlocal
  196.      else
  197.       current@initlocal = 4
  198.       load dword@initlocal dword from name+position@initlocal
  199.      end if
  200.     end virtual
  201.     if current@initlocal = 1
  202.         mov     byte [name+position@initlocal], byte@initlocal
  203.     else if current@initlocal = 2
  204.         mov     word [name+position@initlocal], word@initlocal
  205.     else
  206.         mov     dword [name+position@initlocal], dword@initlocal
  207.     end if
  208.     position@initlocal = position@initlocal + current@initlocal
  209.    end while }
  210.  
  211. macro endp
  212.  { purge ret,locals,endl
  213.    finish@proc
  214.    purge finish@proc
  215.    restore regs@proc
  216.    match all,args@proc \{ restore all \}
  217.    restore args@proc
  218.    match all,all@vars \{ restore all \} }
  219.  
  220. macro local [var]
  221.  { common
  222.     locals
  223.    forward done@local equ
  224.     match varname[count]:vartype, var
  225.     \{ match =BYTE, vartype \\{ varname rb count
  226.                                 restore done@local \\}
  227.        match =WORD, vartype \\{ varname rw count
  228.                                 restore done@local \\}
  229.        match =DWORD, vartype \\{ varname rd count
  230.                                  restore done@local \\}
  231.        match =PWORD, vartype \\{ varname rp count
  232.                                  restore done@local \\}
  233.        match =QWORD, vartype \\{ varname rq count
  234.                                  restore done@local \\}
  235.        match =TBYTE, vartype \\{ varname rt count
  236.                                  restore done@local \\}
  237.        match =DQWORD, vartype \\{ label varname dqword
  238.                                   rq count+count
  239.                                   restore done@local \\}
  240.        match , done@local \\{ virtual
  241.                                varname vartype
  242.                               end virtual
  243.                               rb count*sizeof.\#vartype
  244.                               restore done@local \\} \}
  245.     match :varname:vartype, done@local:var
  246.     \{ match =BYTE, vartype \\{ varname db ?
  247.                                 restore done@local \\}
  248.        match =WORD, vartype \\{ varname dw ?
  249.                                 restore done@local \\}
  250.        match =DWORD, vartype \\{ varname dd ?
  251.                                  restore done@local \\}
  252.        match =PWORD, vartype \\{ varname dp ?
  253.                                  restore done@local \\}
  254.        match =QWORD, vartype \\{ varname dq ?
  255.                                  restore done@local \\}
  256.        match =TBYTE, vartype \\{ varname dt ?
  257.                                  restore done@local \\}
  258.        match =DQWORD, vartype \\{ label varname dqword
  259.                                   dq ?,?
  260.                                   restore done@local \\}
  261.        match , done@local \\{ varname vartype
  262.                               restore done@local \\} \}
  263.     match ,done@local
  264.     \{ var
  265.        restore done@local \}
  266.    common
  267.     endl }
  268.