Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

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