Subversion Repositories Kolibri OS

Rev

Rev 5363 | Blame | Compare with Previous | Last modification | View Log | Download | 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.  { local loc
  59.    loc = (localbytes+3) and (not 3)
  60.    parmbase@proc equ ebp+8
  61.    localbase@proc equ ebp-loc
  62.    if parmbytes | localbytes
  63.         push    ebp
  64.         mov     ebp, esp
  65.     if localbytes
  66.         sub     esp, loc
  67.     end if
  68.    end if
  69.    irps reg, reglist \{ push reg \} }
  70.  
  71. epilogue@proc equ epiloguedef
  72.  
  73. macro epiloguedef procname,flag,parmbytes,localbytes,reglist
  74.  { irps reg, reglist \{ reverse pop reg \}
  75.    if parmbytes | localbytes
  76.         leave
  77.    end if
  78.    if flag and 10000b
  79.         retn
  80.    else
  81.         retn    parmbytes
  82.    end if }
  83.  
  84. close@proc equ
  85.  
  86. macro define@proc name,statement
  87.  { local params,flag,regs,parmbytes,localbytes,current
  88.    if used name
  89.    name:
  90.    match =stdcall args, statement \{ params equ args
  91.                                      flag = 11b \}
  92.    match =stdcall, statement \{ params equ
  93.                                 flag = 11b \}
  94.    match =c args, statement \{ params equ args
  95.                                flag = 10001b \}
  96.    match =c, statement \{ params equ
  97.                           flag = 10001b \}
  98.    match =params, params \{ params equ statement
  99.                             flag = 0 \}
  100.    match =uses reglist=,args, params \{ regs equ reglist
  101.                                         params equ args \}
  102.    match =regs =uses reglist, regs params \{ regs equ reglist
  103.                                              params equ \}
  104.    match =regs, regs \{ regs equ \}
  105.    match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
  106.    virtual at parmbase@proc
  107.    match =,args, params \{ defargs@proc args \}
  108.    match =args@proc args, args@proc params \{ defargs@proc args \}
  109.    parmbytes = $-(parmbase@proc)
  110.    end virtual
  111.    name # % = parmbytes/4
  112.    all@vars equ
  113.    current = 0
  114.    macro locals
  115.    \{ virtual at localbase@proc+current
  116.       macro label def \\{ match . type,def> \\\{ deflocal@proc .,label,<type \\\} \\}
  117.       struc db [val] \\{ \common deflocal@proc .,db,val \\}
  118.       struc du [val] \\{ \common deflocal@proc .,du,val \\}
  119.       struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
  120.       struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
  121.       struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
  122.       struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
  123.       struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
  124.       struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
  125.       struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
  126.       struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
  127.       struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
  128.       struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
  129.       struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
  130.    macro endl
  131.    \{ purge label
  132.       restruc db,du,dw,dp,dd,dt,dq
  133.       restruc rb,rw,rp,rd,rt,rq
  134.       current = $-(localbase@proc)
  135.       end virtual \}
  136.    macro ret operand
  137.    \{ match any, operand \\{ retn operand \\}
  138.       match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
  139.    macro finish@proc
  140.    \{ localbytes = current
  141.       match close:reglist, close@proc:<regs> \\{ close name,flag,parmbytes,localbytes,reglist \\}
  142.       end if \} }
  143.  
  144. macro defargs@proc [arg]
  145.  { common
  146.     if ~ arg eq
  147.    forward
  148.      local ..arg,current@arg
  149.      match argname:type, arg
  150.       \{ current@arg equ argname
  151.          label ..arg type
  152.          argname equ ..arg
  153.          if dqword eq type
  154.            dd ?,?,?,?
  155.          else if tbyte eq type
  156.            dd ?,?,?
  157.          else if qword eq type | pword eq type
  158.            dd ?,?
  159.          else
  160.            dd ?
  161.          end if \}
  162.      match =current@arg,current@arg
  163.       \{ current@arg equ arg
  164.          arg equ ..arg
  165.          ..arg dd ? \}
  166.    common
  167.      args@proc equ current@arg
  168.    forward
  169.      restore current@arg
  170.    common
  171.     end if }
  172.  
  173. macro deflocal@proc name,def,[val] { name def val }
  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 =?, val \{ ..tmp equ \}
  184.     match any (=?), val \{ ..tmp equ \}
  185.     match =label, def \{ ..tmp equ \}
  186.     match tmp : value, ..tmp : val
  187.      \{ tmp: end virtual
  188.         initlocal@proc ..var,def value
  189.         virtual at tmp\}
  190.    common
  191.     match first rest, ..var, \{ name equ first \} }
  192.  
  193. struc label type { label . type }
  194.  
  195. macro initlocal@proc name,def
  196.  { virtual at name
  197.     def
  198.     size@initlocal = $ - name
  199.    end virtual
  200.    position@initlocal = 0
  201.    while size@initlocal > position@initlocal
  202.     virtual at name
  203.      def
  204.      if size@initlocal - position@initlocal < 2
  205.       current@initlocal = 1
  206.       load byte@initlocal byte from name+position@initlocal
  207.      else if size@initlocal - position@initlocal < 4
  208.       current@initlocal = 2
  209.       load word@initlocal word from name+position@initlocal
  210.      else
  211.       current@initlocal = 4
  212.       load dword@initlocal dword from name+position@initlocal
  213.      end if
  214.     end virtual
  215.     if current@initlocal = 1
  216.         mov     byte [name+position@initlocal], byte@initlocal
  217.     else if current@initlocal = 2
  218.         mov     word [name+position@initlocal], word@initlocal
  219.     else
  220.         mov     dword [name+position@initlocal], dword@initlocal
  221.     end if
  222.     position@initlocal = position@initlocal + current@initlocal
  223.    end while }
  224.  
  225. macro endp
  226.  { purge ret,locals,endl
  227.    finish@proc
  228.    purge finish@proc
  229.    restore regs@proc
  230.    match all,args@proc \{ restore all \}
  231.    restore args@proc
  232.    match all,all@vars \{ restore all \} }
  233.  
  234. macro local [var]
  235.  { common
  236.     locals
  237.    forward done@local equ
  238.     match varname[count]:vartype, var
  239.     \{ match =BYTE, vartype \\{ varname rb count
  240.                                 restore done@local \\}
  241.        match =WORD, vartype \\{ varname rw count
  242.                                 restore done@local \\}
  243.        match =DWORD, vartype \\{ varname rd count
  244.                                  restore done@local \\}
  245.        match =PWORD, vartype \\{ varname rp count
  246.                                  restore done@local \\}
  247.        match =QWORD, vartype \\{ varname rq count
  248.                                  restore done@local \\}
  249.        match =TBYTE, vartype \\{ varname rt count
  250.                                  restore done@local \\}
  251.        match =DQWORD, vartype \\{ label varname dqword
  252.                                   rq count+count
  253.                                   restore done@local \\}
  254.        match , done@local \\{ virtual
  255.                                varname vartype
  256.                               end virtual
  257.                               rb count*sizeof.\#vartype
  258.                               restore done@local \\} \}
  259.     match :varname:vartype, done@local:var
  260.     \{ match =BYTE, vartype \\{ varname db ?
  261.                                 restore done@local \\}
  262.        match =WORD, vartype \\{ varname dw ?
  263.                                 restore done@local \\}
  264.        match =DWORD, vartype \\{ varname dd ?
  265.                                  restore done@local \\}
  266.        match =PWORD, vartype \\{ varname dp ?
  267.                                  restore done@local \\}
  268.        match =QWORD, vartype \\{ varname dq ?
  269.                                  restore done@local \\}
  270.        match =TBYTE, vartype \\{ varname dt ?
  271.                                  restore done@local \\}
  272.        match =DQWORD, vartype \\{ label varname dqword
  273.                                   dq ?,?
  274.                                   restore done@local \\}
  275.        match , done@local \\{ varname vartype
  276.                               restore done@local \\} \}
  277.     match ,done@local
  278.     \{ var
  279.        restore done@local \}
  280.    common
  281.     endl }
  282.