stack_chg.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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(line_p l, char sign)
  16. {
  17. /* Interpret the string in the third column of the em_table file */
  18. char *s;
  19. bool argdef;
  20. short arg = 0;
  21. int sum = 0;
  22. line_p p = PREV(l);
  23. line_p pp = (p == (line_p) 0 ? (line_p) 0 : PREV(p));
  24. short i = INSTR(l);
  25. if (i < sp_fmnem || i > sp_lmnem) {
  26. return 0;
  27. }
  28. if (TYPE(l) == OPSHORT) {
  29. arg = SHORT(l);
  30. if (arg < ws) {
  31. /* E.g. a LOI 1 loads word-size bytes,
  32. * not 1 byte!
  33. */
  34. arg = ws;
  35. }
  36. argdef = TRUE;
  37. } else {
  38. argdef = FALSE;
  39. }
  40. s = pop_push[i];
  41. if (*s == '0') return 0;
  42. while (*s != '\0') {
  43. if (*s++ == sign) {
  44. switch(*s) {
  45. case 'w':
  46. sum += ws;
  47. break;
  48. case 'd':
  49. sum += 2 * ws;
  50. break;
  51. case 'p':
  52. sum += ps;
  53. break;
  54. case 'a':
  55. if (!argdef) return -1;
  56. sum += arg;
  57. break;
  58. case 'x':
  59. if (IS_LOC(p)) {
  60. sum += SHORT(p);
  61. break;
  62. } else {
  63. return -1;
  64. }
  65. case 'y':
  66. if (IS_LOC(pp)) {
  67. sum += SHORT(pp);
  68. break;
  69. } else {
  70. return -1;
  71. }
  72. case '?':
  73. return -1;
  74. default:
  75. assert(FALSE);
  76. }
  77. }
  78. s++;
  79. }
  80. return sum;
  81. }
  82. void line_change(line_p l, bool *ok_out, int *pop_out, int *push_out)
  83. {
  84. short pop,push;
  85. pop = stack_change(l,'-');
  86. push = stack_change(l,'+');
  87. *ok_out = (pop != -1 && push != -1);
  88. *pop_out = pop;
  89. *push_out = push;
  90. }