Subversion Repositories Kolibri OS

Rev

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