Subversion Repositories Kolibri OS

Rev

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