/** @file * Sources of the "ARRAY" group instructions */ /* $Id$ */ #include "em_abs.h" #include "global.h" #include "log.h" #include "trap.h" #include "mem.h" #include "text.h" #include "fra.h" #include "switch.h" #define LAR 1 #define SAR 2 #define AAR 3 PRIVATE void arr(int, size); void DoLAR(size arg) { /* LAR w: Load array element, descriptor contains integers of size w */ LOG(("@A6 DoLAR(%ld)", arg)); arr(LAR, arg_wi(arg)); } void DoSAR(size arg) { /* SAR w: Store array element */ LOG(("@A6 DoSAR(%ld)", arg)); arr(SAR, arg_wi(arg)); } void DoAAR(size arg) { /* AAR w: Load address of array element */ LOG(("@A6 DoAAR(%ld)", arg)); arr(AAR, arg_wi(arg)); } /******************************************************** * Array arithmetic * * * * 1. The address of the descriptor is popped. * * 2. The index is popped. * * 3. Calculate index - lower bound. * * 4. Check if in range. * * 5. Calculate object size. * * 6. Perform the correct function. * *********************************************************/ PRIVATE void arr(int type, /* operation TYPE */ size elm_size /* ELeMent SIZE */ ) { register ptr desc = dppop(); /* array DESCriptor */ register size obj_size; /* OBJect SIZE */ long index = spop(elm_size); long diff = /* between index and lower bound */ index - mem_lds(desc, elm_size); register ptr arr_addr = dppop();/* ARRay ADDRess */ if (must_test && !(IgnMask&BIT(EARRAY))) { if (diff < 0 || index > mem_lds(desc + elm_size, elm_size)) { trap(EARRAY); } } obj_size = mem_lds(desc + (2*elm_size), elm_size); obj_size = arg_o(((long) obj_size)); spoilFRA(); /* array functions don't retain FRA */ switch (type) { case LAR: push_m(arr_addr + diff * obj_size, obj_size); break; case SAR: pop_m(arr_addr + diff * obj_size, obj_size); break; case AAR: dppush(arr_addr + diff * obj_size); break; } }