Subversion Repositories Kolibri OS

Rev

Rev 617 | Blame | Compare with Previous | Last modification | View Log | RSS feed

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