Subversion Repositories Kolibri OS

Rev

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

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