stack_chg.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /* S T A C K _ C H A N G E . C */
  7. #include <stdio.h>
  8. #include <em_spec.h>
  9. #include <em_mnem.h>
  10. #include "types.h"
  11. #include "debug.h"
  12. #include "global.h"
  13. #include "pop_push.h"
  14. #define IS_LOC(l) (l!=(line_p) 0 && INSTR(l)==op_loc && TYPE(l)==OPSHORT)
  15. int stack_change(l,sign)
  16. line_p l;
  17. char sign;
  18. {
  19. /* Interpret the string in the third column of the em_table file */
  20. char *s;
  21. bool argdef;
  22. short arg = 0;
  23. int sum = 0;
  24. line_p p = PREV(l);
  25. line_p pp = (p == (line_p) 0 ? (line_p) 0 : PREV(p));
  26. short i = INSTR(l);
  27. if (i < sp_fmnem || i > sp_lmnem) {
  28. return 0;
  29. }
  30. if (TYPE(l) == OPSHORT) {
  31. arg = SHORT(l);
  32. if (arg < ws) {
  33. /* E.g. a LOI 1 loads word-size bytes,
  34. * not 1 byte!
  35. */
  36. arg = ws;
  37. }
  38. argdef = TRUE;
  39. } else {
  40. argdef = FALSE;
  41. }
  42. s = pop_push[i];
  43. if (*s == '0') return 0;
  44. while (*s != '\0') {
  45. if (*s++ == sign) {
  46. switch(*s) {
  47. case 'w':
  48. sum += ws;
  49. break;
  50. case 'd':
  51. sum += 2 * ws;
  52. break;
  53. case 'p':
  54. sum += ps;
  55. break;
  56. case 'a':
  57. if (!argdef) return -1;
  58. sum += arg;
  59. break;
  60. case 'x':
  61. if (IS_LOC(p)) {
  62. sum += SHORT(p);
  63. break;
  64. } else {
  65. return -1;
  66. }
  67. case 'y':
  68. if (IS_LOC(pp)) {
  69. sum += SHORT(pp);
  70. break;
  71. } else {
  72. return -1;
  73. }
  74. case '?':
  75. return -1;
  76. default:
  77. assert(FALSE);
  78. }
  79. }
  80. s++;
  81. }
  82. return sum;
  83. }
  84. line_change(l,ok_out,pop_out,push_out)
  85. line_p l;
  86. bool *ok_out;
  87. int *pop_out,*push_out;
  88. {
  89. short pop,push;
  90. pop = stack_change(l,'-');
  91. push = stack_change(l,'+');
  92. *ok_out = (pop != -1 && push != -1);
  93. *pop_out = pop;
  94. *push_out = push;
  95. }