home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cc-61.0.1 / cc / config / m88k-trace.asm < prev    next >
Assembly Source File  |  1991-06-03  |  11KB  |  488 lines

  1. ; Source for routine to check for preserved registers being
  2. ; clobbered on the Motorola 88000.
  3. ;
  4. ; Copyright (C) 1989 Free Software Foundation, Inc.
  5. ;
  6. ; This file is part of GNU CC.
  7. ;
  8. ; GNU CC is free software; you can redistribute it and/or modify
  9. ; it under the terms of the GNU General Public License as published by
  10. ; the Free Software Foundation; either version 2, or (at your option)
  11. ; any later version.
  12. ;
  13. ; GNU CC is distributed in the hope that it will be useful,
  14. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. ; GNU General Public License for more details.
  17. ;
  18. ; You should have received a copy of the GNU General Public License
  19. ; along with GNU CC; see the file COPYING.  If not, write to
  20. ; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21. ;
  22. ; Routine to find places where preserved registers aren't and other
  23. ; anonomilies.  It is intended to be used with GCC's -mtrace-function
  24. ; which calls "__enter" at function prologue time, and "__leave" at
  25. ; function epilogue time, and uses the following calling sequence:
  26. ;
  27. ; r1        -- return address
  28. ; r2  - r9    -- caller parameter registers
  29. ; r10        -- pointer to a dope vector
  30. ; r11        -- not used (static chain if needed)
  31. ; r12        -- structure return address
  32. ; r13        -- return address of the caller (was r1)
  33. ; r14 - r31    -- preserved register set
  34. ;
  35. ; The dope vector has the following format:
  36. ;
  37. ;    word 0    -- # words following (4 currently)
  38. ;    word 1    -- pointer to function name string
  39. ;    word 2    -- # bytes in the function name string
  40. ;    word 3    -- bit mask of fixed register (normally 0, 30, 31)
  41. ;    word 4    -- bit mask of call preserved registers
  42. ;
  43. ; Note, the Motorola Anglefire uses r24 as a temporary, which is
  44. ; normally a call used register in the GNU/Green Hills compilers.
  45. ; So we slow this routine down even more than it already is....
  46. ;
  47. ; Upon exit, r2-r9, r13-r31 should be the same as upon entry.
  48. ; The traceback code assumes a system V/ANSI style sprintf for
  49. ; simplicity sake (ie, r2 holds the # bytes in the message after
  50. ; the call, rather than the buffer pointer).
  51. ;
  52. ; Due to it's use of a global pointer, and an instruction window
  53. ; use of this routine within signal handlers is not recommended.
  54.  
  55.     file    "m88k-trace.s"
  56.     global    __enter
  57.     global    __leave
  58.     global    __trace_ptr
  59.     global    __trace_count
  60.     global    __trace_temp
  61.  
  62.     text                    ; error messages
  63.     align    4
  64. fmt:    string    "%-33.32s(%.8x %.8x %.8x %.8x) %.8x\n"
  65.  
  66.     align    4
  67. enest:    string    "__enter: too many nested calls.\012\000"
  68.  
  69.     align    4
  70. ewrong:    string    "__leave: internal stack messed up.\012\000"
  71.  
  72.     align    4
  73. eret:    string    "__leave: return address trashed.\012\000"
  74.  
  75.     align    4
  76. e14:    string    "__leave: register r14 trashed.\012\000"
  77.  
  78.     align    4
  79. e15:    string    "__leave: register r15 trashed.\012\000"
  80.  
  81.     align    4
  82. e16:    string    "__leave: register r16 trashed.\012\000"
  83.  
  84.     align    4
  85. e17:    string    "__leave: register r17 trashed.\012\000"
  86.  
  87.     align    4
  88. e18:    string    "__leave: register r18 trashed.\012\000"
  89.  
  90.     align    4
  91. e19:    string    "__leave: register r19 trashed.\012\000"
  92.  
  93.     align    4
  94. e20:    string    "__leave: register r20 trashed.\012\000"
  95.  
  96.     align    4
  97. e21:    string    "__leave: register r21 trashed.\012\000"
  98.  
  99.     align    4
  100. e22:    string    "__leave: register r22 trashed.\012\000"
  101.  
  102.     align    4
  103. e23:    string    "__leave: register r23 trashed.\012\000"
  104.  
  105.     align    4
  106. e24:    string    "__leave: register r24 trashed.\012\000"
  107.  
  108.     align    4
  109. e25:    string    "__leave: register r25 trashed.\012\000"
  110.  
  111.     align    4
  112. e26:    string    "__leave: register r26 trashed.\012\000"
  113.  
  114.     align    4
  115. e27:    string    "__leave: register r27 trashed.\012\000"
  116.  
  117.     align    4
  118. e28:    string    "__leave: register r28 trashed.\012\000"
  119.  
  120.     align    4
  121. e29:    string    "__leave: register r29 trashed.\012\000"
  122.  
  123.     align    4
  124. e30:    string    "__leave: register r30 trashed.\012\000"
  125.  
  126.     align    4
  127. e31:    string    "__leave: register r31 trashed.\012\000"
  128.  
  129.  
  130.     def    size,8192            ; define internal stack
  131.     bss    save,size,8            ; to save preserved regs
  132.  
  133.     def    dope,0                ; offset for storing dope
  134.     def    s2,dope+4            ; offset for storing r2
  135.     def    s3,s2+4                ; offset for storing r3
  136.     def    s4,s3+4                ; offset for storing r4
  137.     def    s5,s4+4                ; offset for storing r5
  138.     def    s6,s5+4                ; offset for storing r6
  139.     def    s7,s6+4                ; offset for storing r7
  140.     def    s8,s7+4                ; offset for storing r8
  141.     def    s9,s8+4                ; offset for storing r9
  142.     def    s13,s9+4            ; offset for storing r13
  143.     def    s14,s13+4            ; offset for storing r14
  144.     def    s15,s14+4            ; offset for storing r15
  145.     def    s16,s15+4            ; offset for storing r16
  146.     def    s17,s16+4            ; offset for storing r17
  147.     def    s18,s17+4            ; offset for storing r18
  148.     def    s19,s18+4            ; offset for storing r19
  149.     def    s20,s19+4            ; offset for storing r20
  150.     def    s21,s20+4            ; offset for storing r21
  151.     def    s22,s21+4            ; offset for storing r22
  152.     def    s23,s22+4            ; offset for storing r23
  153.     def    s24,s23+4            ; offset for storing r24
  154.     def    s25,s24+4            ; offset for storing r25
  155.     def    s26,s25+4            ; offset for storing r26
  156.     def    s27,s26+4            ; offset for storing r27
  157.     def    s28,s27+4            ; offset for storing r28
  158.     def    s29,s28+4            ; offset for storing r29
  159.     def    s30,s29+4            ; offset for storing r30
  160.     def    s31,s30+4            ; offset for storing r31
  161.  
  162.     def    blksize,s31+4            ; size of the block needed
  163.     def    end,save+size-(2*blksize)    ; end of the private stack
  164.  
  165.     def    dcount,0            ; dope offset for word count
  166.     def    dname,dcount+4            ; dope offset for function name
  167.     def    dlen,dname+4            ; dope offset for name length
  168.     def    dfixed,dlen+4            ; dope offset for fixed regs
  169.     def    dcall,dfixed+4            ; dope offset for call used regs
  170.  
  171.     data
  172.     align    4
  173. __trace_ptr:                    ; pointer to current save
  174.     word    save-blksize            ; area
  175.  
  176. __trace_temp:
  177.     word    0                ; temp for traceback
  178.  
  179. __trace_count:
  180.     word    0                ; # of trace calls
  181.  
  182.     bss    buffer,200,4            ; buffer for sprintf
  183.  
  184.     text
  185.     align    4
  186. __enter:
  187.     or.u    r11,r0,hi16(__trace_ptr)    ; allocate next block
  188.     ld    r11,r11,lo16(__trace_ptr)
  189.     addu    r11,r11,blksize
  190.     st    r10,r11,dope            ; save the dope vector
  191.     or.u    r10,r0,hi16(__trace_ptr)
  192.     st    r11,r10,lo16(__trace_ptr)
  193.  
  194.     st    r2,r11,s2            ; save the arguments
  195.     st    r3,r11,s3
  196.     st    r4,r11,s4
  197.     st    r5,r11,s5
  198.     st    r6,r11,s6
  199.     st    r7,r11,s7
  200.     st    r8,r11,s8
  201.     st    r9,r11,s9
  202.  
  203.     st    r13,r11,s13            ; save the preserved registers
  204.     st    r14,r11,s14
  205.     st    r15,r11,s15
  206.     st    r16,r11,s16
  207.     st    r17,r11,s17
  208.     st    r18,r11,s18
  209.     st    r19,r11,s19
  210.     st    r20,r11,s20
  211.     st    r21,r11,s21
  212.     st    r22,r11,s22
  213.     st    r23,r11,s23
  214.     st    r24,r11,s24
  215.     st    r25,r11,s25
  216.     st    r26,r11,s26
  217.     st    r27,r11,s27
  218.     st    r28,r11,s28
  219.     st    r29,r11,s29
  220.     st    r30,r11,s30
  221.     st    r31,r11,s31
  222.  
  223.     or.u    r10,r0,hi16(end)        ; too deeply nested?
  224.     or    r10,r10,lo16(end)
  225.     cmp    r10,r11,r10
  226.     bb1    ge,r10,anest            ; abort if overflow
  227.  
  228.     or.u    r10,r0,hi16(__trace_count)    ; bump # calls
  229.     ld    r11,r10,lo16(__trace_count)
  230.     addu    r11,r11,1
  231.     st    r11,r10,lo16(__trace_count)
  232.     jmp    r1                ; return to the caller
  233.  
  234. anest:
  235.     or.u    r2,r0,hi16(enest)        ; nesting overflow msg
  236.     or    r2,r2,lo16(enest)
  237.     br    abend
  238.  
  239. __leave:
  240.     or.u    r11,r0,hi16(__trace_ptr)    ; get the preserved regs
  241.     ld    r11,r11,lo16(__trace_ptr)
  242.     ld    r12,r11,dope            ; now check everything's
  243.     cmp    r12,r12,r10
  244.     bb1    ne,r12,awrong
  245.  
  246. ; Get the fixed registers (those which should be ignored by this
  247. ; routine) and the call used registers (those which are ok to
  248. ; trash).  Note the most significant bit (ie, the sign bit) represents
  249. ; r31, while the least significant bit represents r0.  Even though
  250. ; r28-r26 are treated as fixed by GNU, we will consider them as not
  251. ; fixed to track down who might be modifying them, so we can use them
  252. ; for literal synthesis.  At the moment, assume r29 is fixed because
  253. ; the Motorola 0.6 linker will use r29 as a general scratch register.
  254.  
  255.     ld    r10,r10,dfixed            ; fixed registers
  256.     and.u    r10,r10,hi16(0xe3ffffff)    ; unfix special regs
  257.  
  258.     ld    r12,r11,s13
  259.     cmp    r12,r12,r13
  260.     bb1    ne,r12,aret
  261.  
  262.     bb1    14,r10,l15
  263.     ld    r12,r11,s14
  264.     cmp    r12,r12,r14
  265.     bb1    ne,r12,a14
  266.  
  267. l15:    bb1    15,r10,l16
  268.     ld    r12,r11,s15
  269.     cmp    r12,r12,r15
  270.     bb1    ne,r12,a15
  271.  
  272. l16:    bb1    16,r10,l17
  273.     ld    r12,r11,s16
  274.     cmp    r12,r12,r16
  275.     bb1    ne,r12,a16
  276.  
  277. l17:    bb1    17,r10,l18
  278.     ld    r12,r11,s17
  279.     cmp    r12,r12,r17
  280.     bb1    ne,r12,a17
  281.  
  282. l18:    bb1    18,r10,l19
  283.     ld    r12,r11,s18
  284.     cmp    r12,r12,r18
  285.     bb1    ne,r12,a18
  286.  
  287. l19:    bb1    19,r10,l20
  288.     ld    r12,r11,s19
  289.     cmp    r12,r12,r19
  290.     bb1    ne,r12,a19
  291.  
  292. l20:    bb1    20,r10,l21
  293.     ld    r12,r11,s20
  294.     cmp    r12,r12,r20
  295.     bb1    ne,r12,a20
  296.  
  297. l21:    bb1    21,r10,l22
  298.     ld    r12,r11,s21
  299.     cmp    r12,r12,r21
  300.     bb1    ne,r12,a21
  301.  
  302. l22:    bb1    22,r10,l23
  303.     ld    r12,r11,s22
  304.     cmp    r12,r12,r22
  305.     bb1    ne,r12,a22
  306.  
  307. l23:    bb1    23,r10,l24
  308.     ld    r12,r11,s23
  309.     cmp    r12,r12,r23
  310.     bb1    ne,r12,a23
  311.  
  312. l24:    bb1    24,r10,l25
  313.     ld    r12,r11,s24
  314.     cmp    r12,r12,r24
  315.     bb1    ne,r12,a24
  316.  
  317. l25:    bb1    25,r10,l26
  318.     ld    r12,r11,s25
  319.     cmp    r12,r12,r25
  320.     bb1    ne,r12,a25
  321.  
  322. l26:    bb1    26,r10,l27
  323.     ld    r12,r11,s26
  324.     cmp    r12,r12,r26
  325.     bb1    ne,r12,a26
  326.  
  327. l27:    bb1    27,r10,l28
  328.     ld    r12,r11,s27
  329.     cmp    r12,r12,r27
  330.     bb1    ne,r12,a27
  331.  
  332. l28:    bb1    28,r10,l29
  333.     ld    r12,r11,s28
  334.     cmp    r12,r12,r28
  335.     bb1    ne,r12,a28
  336.  
  337. l29:    bb1    29,r10,l30
  338.     ld    r12,r11,s29
  339.     cmp    r12,r12,r29
  340.     bb1    ne,r12,a29
  341.  
  342. l30:    bb1    30,r10,l31
  343.     ld    r12,r11,s30
  344.     cmp    r12,r12,r30
  345.     bb1    ne,r12,a30
  346.  
  347. l31:    bb1    31,r10,lok
  348.     ld    r12,r11,s31
  349.     cmp    r12,r12,r31
  350.     bb1    ne,r12,a31
  351.  
  352. lok:    subu    r11,r11,blksize            ; decrement stack now
  353.     or.u    r12,r0,hi16(__trace_ptr)
  354.     st    r11,r12,lo16(__trace_ptr)
  355.     jmp    r1
  356.  
  357. ; Labels to load r2 with the error message addres, and jump to
  358. ; common abort processing
  359.  
  360. awrong:    or.u    r2,r0,hi16(ewrong)
  361.     or    r2,r2,lo16(ewrong)
  362.     br    abend
  363.  
  364. aret:    or.u    r2,r0,hi16(eret)
  365.     or    r2,r2,lo16(eret)
  366.     br    abend
  367.  
  368. a14:    or.u    r2,r0,hi16(e14)
  369.     or    r2,r2,lo16(e14)
  370.     br    abend
  371.  
  372. a15:    or.u    r2,r0,hi16(e15)
  373.     or    r2,r2,lo16(e15)
  374.     br    abend
  375.  
  376. a16:    or.u    r2,r0,hi16(e16)
  377.     or    r2,r2,lo16(e16)
  378.     br    abend
  379.  
  380. a17:    or.u    r2,r0,hi16(e17)
  381.     or    r2,r2,lo16(e17)
  382.     br    abend
  383.  
  384. a18:    or.u    r2,r0,hi16(e18)
  385.     or    r2,r2,lo16(e18)
  386.     br    abend
  387.  
  388. a19:    or.u    r2,r0,hi16(e19)
  389.     or    r2,r2,lo16(e19)
  390.     br    abend
  391.  
  392. a20:    or.u    r2,r0,hi16(e20)
  393.     or    r2,r2,lo16(e20)
  394.     br    abend
  395.  
  396. a21:    or.u    r2,r0,hi16(e21)
  397.     or    r2,r2,lo16(e21)
  398.     br    abend
  399.  
  400. a22:    or.u    r2,r0,hi16(e22)
  401.     or    r2,r2,lo16(e22)
  402.     br    abend
  403.  
  404. a23:    or.u    r2,r0,hi16(e23)
  405.     or    r2,r2,lo16(e23)
  406.     br    abend
  407.  
  408. a24:    or.u    r2,r0,hi16(e24)
  409.     or    r2,r2,lo16(e24)
  410.     br    abend
  411.  
  412. a25:    or.u    r2,r0,hi16(e25)
  413.     or    r2,r2,lo16(e25)
  414.     br    abend
  415.  
  416. a26:    or.u    r2,r0,hi16(e26)
  417.     or    r2,r2,lo16(e26)
  418.     br    abend
  419.  
  420. a27:    or.u    r2,r0,hi16(e27)
  421.     or    r2,r2,lo16(e27)
  422.     br    abend
  423.  
  424. a28:    or.u    r2,r0,hi16(e28)
  425.     or    r2,r2,lo16(e28)
  426.     br    abend
  427.  
  428. a29:    or.u    r2,r0,hi16(e29)
  429.     or    r2,r2,lo16(e29)
  430.     br    abend
  431.  
  432. a30:    or.u    r2,r0,hi16(e30)
  433.     or    r2,r2,lo16(e30)
  434.     br    abend
  435.  
  436. a31:    or.u    r2,r0,hi16(e31)
  437.     or    r2,r2,lo16(e31)
  438.     br    abend
  439.  
  440. ; Common abort processing, r2 = error message
  441.  
  442. abend:    or    r3,r2,r0            ; save for write sys call
  443.  
  444. aloop:    ld.b    r5,r2,r0            ; while (*p++) count++
  445.     addu    r2,r2,1
  446.     bcnd    ne0,r5,aloop
  447.  
  448.     subu    r4,r2,r3            ; # bytes
  449.     or    r2,r0,2                ; stderr channel
  450.     bsr    __write                ; complain
  451.  
  452. ; Print a stack traceback
  453.  
  454.     or.u    r13,r0,hi16(__trace_ptr)
  455.     ld    r13,r13,lo16(__trace_ptr)
  456.     addu    r13,r13,blksize            ; offset for loop
  457.     or.u    r10,r0,hi16(__trace_temp)
  458.     st    r13,r10,lo16(__trace_temp)
  459.  
  460. atrace:    or.u    r10,r0,hi16(__trace_temp)    ; format traceback
  461.     ld    r13,r10,lo16(__trace_temp)
  462.     subu    r13,r13,blksize            ; go to previous frame
  463.     st    r13,r10,lo16(__trace_temp)
  464.  
  465.     or.u    r10,r0,hi16(save)
  466.     or    r10,r10,lo16(save)
  467.     tbnd    r10,r13                ; trap if we are done
  468.  
  469.     ld    r9,r13,s31
  470.     ld    r8,r13,s5
  471.     ld    r7,r13,s4
  472.     ld    r6,r13,s3
  473.     ld    r5,r13,s2
  474.     ld    r4,r13,dope
  475.     ld    r4,r4,dname
  476.     or.u    r3,r0,hi16(fmt)
  477.     or    r3,r3,lo16(fmt)
  478.     or.u    r2,r0,hi16(buffer)
  479.     or    r2,r2,lo16(buffer)
  480.     bsr    _sprintf
  481.  
  482.     or.u    r3,r0,hi16(buffer)
  483.     or    r3,r3,lo16(buffer)
  484.     or    r4,r2,r0            ; # bytes to write
  485.     or    r2,r0,2                ; standard error
  486.     bsr    __write                ; write traceback
  487.     br    atrace
  488.