do_array.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * Sources of the "ARRAY" group instructions
  3. */
  4. /* $Id$ */
  5. #include <em_abs.h>
  6. #include "global.h"
  7. #include "log.h"
  8. #include "trap.h"
  9. #include "mem.h"
  10. #include "text.h"
  11. #include "fra.h"
  12. #define LAR 1
  13. #define SAR 2
  14. #define AAR 3
  15. PRIVATE arr();
  16. DoLAR(arg)
  17. size arg;
  18. {
  19. /* LAR w: Load array element, descriptor contains integers of size w */
  20. LOG(("@A6 DoLAR(%ld)", arg));
  21. arr(LAR, arg_wi(arg));
  22. }
  23. DoSAR(arg)
  24. size arg;
  25. {
  26. /* SAR w: Store array element */
  27. LOG(("@A6 DoSAR(%ld)", arg));
  28. arr(SAR, arg_wi(arg));
  29. }
  30. DoAAR(arg)
  31. size arg;
  32. {
  33. /* AAR w: Load address of array element */
  34. LOG(("@A6 DoAAR(%ld)", arg));
  35. arr(AAR, arg_wi(arg));
  36. }
  37. /********************************************************
  38. * Array arithmetic *
  39. * *
  40. * 1. The address of the descriptor is popped. *
  41. * 2. The index is popped. *
  42. * 3. Calculate index - lower bound. *
  43. * 4. Check if in range. *
  44. * 5. Calculate object size. *
  45. * 6. Perform the correct function. *
  46. *********************************************************/
  47. PRIVATE arr(type, elm_size)
  48. int type; /* operation TYPE */
  49. size elm_size; /* ELeMent SIZE */
  50. {
  51. register ptr desc = dppop(); /* array DESCriptor */
  52. register size obj_size; /* OBJect SIZE */
  53. register long diff = /* between index and lower bound */
  54. spop(elm_size) - mem_lds(desc, elm_size);
  55. register ptr arr_addr = dppop();/* ARRay ADDRess */
  56. if (must_test && !(IgnMask&BIT(EARRAY))) {
  57. if (diff < 0 || diff > mem_lds(desc + elm_size, elm_size)) {
  58. trap(EARRAY);
  59. }
  60. }
  61. obj_size = mem_lds(desc + (2*elm_size), elm_size);
  62. obj_size = arg_o(((long) obj_size));
  63. spoilFRA(); /* array functions don't retain FRA */
  64. switch (type) {
  65. case LAR:
  66. push_m(arr_addr + diff * obj_size, obj_size);
  67. break;
  68. case SAR:
  69. pop_m(arr_addr + diff * obj_size, obj_size);
  70. break;
  71. case AAR:
  72. dppush(arr_addr + diff * obj_size);
  73. break;
  74. }
  75. }