Subversion Repositories Kolibri OS

Rev

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