Subversion Repositories Kolibri OS

Rev

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