Subversion Repositories Kolibri OS

Rev

Rev 7294 | Rev 8970 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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