ack/util/int/do_array.c

87 lines
1.9 KiB
C
Raw Normal View History

2019-03-17 14:42:00 +00:00
/** @file
* Sources of the "ARRAY" group instructions
1988-06-22 16:57:09 +00:00
*/
1994-06-24 11:31:16 +00:00
/* $Id$ */
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
#include "em_abs.h"
1988-06-22 16:57:09 +00:00
#include "global.h"
#include "log.h"
#include "trap.h"
#include "mem.h"
#include "text.h"
#include "fra.h"
#include "switch.h"
1988-06-22 16:57:09 +00:00
#define LAR 1
#define SAR 2
#define AAR 3
2019-03-17 14:42:00 +00:00
PRIVATE void arr(int, size);
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
void DoLAR(size arg)
1988-06-22 16:57:09 +00:00
{
/* LAR w: Load array element, descriptor contains integers of size w */
LOG(("@A6 DoLAR(%ld)", arg));
1988-06-22 16:57:09 +00:00
arr(LAR, arg_wi(arg));
}
2019-03-17 14:42:00 +00:00
void DoSAR(size arg)
1988-06-22 16:57:09 +00:00
{
/* SAR w: Store array element */
LOG(("@A6 DoSAR(%ld)", arg));
1988-06-22 16:57:09 +00:00
arr(SAR, arg_wi(arg));
}
2019-03-17 14:42:00 +00:00
void DoAAR(size arg)
1988-06-22 16:57:09 +00:00
{
/* AAR w: Load address of array element */
LOG(("@A6 DoAAR(%ld)", arg));
1988-06-22 16:57:09 +00:00
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. *
*********************************************************/
2019-03-17 14:42:00 +00:00
PRIVATE void arr(int type, /* operation TYPE */
size elm_size /* ELeMent SIZE */
)
1988-06-22 16:57:09 +00:00
{
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);
1988-06-22 16:57:09 +00:00
register ptr arr_addr = dppop();/* ARRay ADDRess */
if (must_test && !(IgnMask&BIT(EARRAY))) {
if (diff < 0 || index > mem_lds(desc + elm_size, elm_size)) {
1988-06-22 16:57:09 +00:00
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;
}
}