Subversion Repositories Kolibri OS

Rev

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