Subversion Repositories Kolibri OS

Rev

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