Subversion Repositories Kolibri OS

Rev

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

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