OpenSolaris_b135/lib/efcode/engine/prims64.c

Compare this file to the similar file:
Show the results in this format:

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 2000 by Sun Microsystems, Inc.
 * All rights reserved.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcode/private.h>
#include <fcdriver/fcdriver.h>

#define	LF_PER_XF	(sizeof (xforth_t)/sizeof (lforth_t))
#define	WF_PER_XF	(sizeof (xforth_t)/sizeof (wforth_t))

void unaligned_xfetch(fcode_env_t *);
void unaligned_xstore(fcode_env_t *);
static void xbsplit(fcode_env_t *);

xforth_t
pop_xforth(fcode_env_t *env)
{
	if (sizeof (xforth_t) == sizeof (fstack_t))
		return (POP(DS));
	return ((xforth_t)pop_double(env));
}

xforth_t
peek_xforth(fcode_env_t *env)
{
	xforth_t d;

	d = pop_xforth(env);
	push_xforth(env, d);
	return (d);
}

void
push_xforth(fcode_env_t *env, xforth_t a)
{
	if (sizeof (xforth_t) == sizeof (fstack_t))
		PUSH(DS, a);
	else
		push_double(env, (dforth_t)a);
}

/*
 * bxjoin     ( b.lo b.2 b.3 b.4 b.5 b.6 b.7 b.hi -- o )
 */
static void
bxjoin(fcode_env_t *env)
{
	union {
		uchar_t b_bytes[sizeof (xforth_t)];
		xforth_t b_xf;
	} b;
	int i;

	CHECK_DEPTH(env, sizeof (xforth_t), "bxjoin");
	for (i = 0; i < sizeof (xforth_t); i++)
		b.b_bytes[i] = POP(DS);
	push_xforth(env, b.b_xf);
}

/*
 * <l@        ( qaddr -- n )
 */
static void
lsfetch(fcode_env_t *env)
{
	s_lforth_t *addr;
	xforth_t a;

	CHECK_DEPTH(env, 1, "<l@");
	addr = (s_lforth_t *)POP(DS);
	a = *addr;
	push_xforth(env, a);
}

/*
 * lxjoin     ( quad.lo quad.hi -- o )
 */
static void
lxjoin(fcode_env_t *env)
{
	union {
		lforth_t b_lf[LF_PER_XF];
		xforth_t b_xf;
	} b;
	int i;

	CHECK_DEPTH(env, LF_PER_XF, "lxjoin");
	for (i = 0; i < LF_PER_XF; i++)
		b.b_lf[i] = POP(DS);
	push_xforth(env, b.b_xf);
}

/*
 * wxjoin     ( w.lo w.2 w.3 w.hi -- o )
 */
static void
wxjoin(fcode_env_t *env)
{
	union {
		wforth_t b_wf[WF_PER_XF];
		xforth_t b_xf;
	} b;
	int i;

	CHECK_DEPTH(env, WF_PER_XF, "wxjoin");
	for (i = 0; i < WF_PER_XF; i++)
		b.b_wf[i] = POP(DS);
	push_xforth(env, b.b_xf);
}

/*
 * x,         ( o -- )
 */
static void
xcomma(fcode_env_t *env)
{
	CHECK_DEPTH(env, 1, "x,");
	DEBUGF(COMMA, dump_comma(env, "x,"));
	PUSH(DS, (fstack_t)HERE);
	unaligned_xstore(env);
	set_here(env, HERE + sizeof (xforth_t), "xcomma");
}

/*
 * x@         ( xaddr  -- o )
 */
void
xfetch(fcode_env_t *env)
{
	xforth_t *addr;
	xforth_t a;

	CHECK_DEPTH(env, 1, "x@");
	addr = (xforth_t *)POP(DS);
	a = *addr;
	push_xforth(env, a);
}

/*
 * x!         ( o xaddr -- )
 */
void
xstore(fcode_env_t *env)
{
	xforth_t *addr;
	xforth_t a;

	CHECK_DEPTH(env, 2, "x!");
	addr = (xforth_t *)POP(DS);
	a = pop_xforth(env);
	*addr = a;
}

/*
 * /x         ( -- n )
 */
static void
slash_x(fcode_env_t *env)
{
	PUSH(DS, sizeof (xforth_t));
}

/*
 * /x*        ( nu1 -- nu2 )
 */
static void
slash_x_times(fcode_env_t *env)
{
	CHECK_DEPTH(env, 1, "/x*");
	TOS *= sizeof (xforth_t);
}

/*
 * xa+        ( addr1 index -- addr2 )
 */
static void
xa_plus(fcode_env_t *env)
{
	fstack_t index;

	CHECK_DEPTH(env, 2, "xa+");
	index = POP(DS);
	TOS += index * sizeof (xforth_t);
}

/*
 * xa1+       ( addr1 -- addr2 )
 */
static void
xa_one_plus(fcode_env_t *env)
{
	CHECK_DEPTH(env, 1, "xa1+");
	TOS += sizeof (xforth_t);
}

/*
 * xbflip     ( oct1 -- oct2 )
 */
void
xbflip(fcode_env_t *env)
{
	union {
		uchar_t b_bytes[sizeof (xforth_t)];
		xforth_t b_xf;
	} b, c;
	int i;

	CHECK_DEPTH(env, 1, "xbflip");
	b.b_xf = pop_xforth(env);
	for (i = 0; i < sizeof (xforth_t); i++)
		c.b_bytes[i] = b.b_bytes[(sizeof (xforth_t) - 1) - i];
	push_xforth(env, c.b_xf);
}

void
unaligned_xfetch(fcode_env_t *env)
{
	fstack_t addr;
	int i;

	CHECK_DEPTH(env, 1, "unaligned-x@");
	addr = POP(DS);
	for (i = 0; i < sizeof (xforth_t); i++, addr++) {
		PUSH(DS, addr);
		cfetch(env);
	}
	bxjoin(env);
	xbflip(env);
}

void
unaligned_xstore(fcode_env_t *env)
{
	fstack_t addr;
	int i;

	CHECK_DEPTH(env, 2, "unaligned-x!");
	addr = POP(DS);
	xbsplit(env);
	for (i = 0; i < sizeof (xforth_t); i++, addr++) {
		PUSH(DS, addr);
		cstore(env);
	}
}

/*
 * xbflips    ( xaddr len -- )
 */
static void
xbflips(fcode_env_t *env)
{
	fstack_t len, addr;
	int i;

	CHECK_DEPTH(env, 2, "xbflips");
	len = POP(DS);
	addr = POP(DS);
	for (i = 0; i < len; i += sizeof (xforth_t),
	    addr += sizeof (xforth_t)) {
		PUSH(DS, addr);
		unaligned_xfetch(env);
		xbflip(env);
		PUSH(DS, addr);
		unaligned_xstore(env);
	}
}

/*
 * xbsplit    ( o -- b.lo b.2 b.3 b.4 b.5 b.6 b.7 b.hi )
 */
static void
xbsplit(fcode_env_t *env)
{
	union {
		uchar_t b_bytes[sizeof (xforth_t)];
		xforth_t b_xf;
	} b;
	int i;

	CHECK_DEPTH(env, 1, "xbsplit");
	b.b_xf = pop_xforth(env);
	for (i = 0; i < sizeof (xforth_t); i++)
		PUSH(DS, b.b_bytes[(sizeof (xforth_t) - 1) - i]);
}

/*
 * xlflip     ( oct1 -- oct2 )
 */
void
xlflip(fcode_env_t *env)
{
	union {
		lforth_t b_lf[LF_PER_XF];
		xforth_t b_xf;
	} b, c;
	int i;

	CHECK_DEPTH(env, 1, "xlflip");
	b.b_xf = pop_xforth(env);
	for (i = 0; i < LF_PER_XF; i++)
		c.b_lf[i] = b.b_lf[(LF_PER_XF - 1) - i];
	push_xforth(env, c.b_xf);
}

/*
 * xlflips    ( xaddr len -- )
 */
static void
xlflips(fcode_env_t *env)
{
	fstack_t len, addr;
	int i;

	CHECK_DEPTH(env, 2, "xlflips");
	len = POP(DS);
	addr = POP(DS);
	for (i = 0; i < len; i += sizeof (xforth_t),
	    addr += sizeof (xforth_t)) {
		PUSH(DS, addr);
		unaligned_xfetch(env);
		xlflip(env);
		PUSH(DS, addr);
		unaligned_xstore(env);
	}
}

/*
 * xlsplit    ( o -- quad.lo quad.hi )
 */
static void
xlsplit(fcode_env_t *env)
{
	union {
		lforth_t b_lf[LF_PER_XF];
		xforth_t b_xf;
	} b;
	int i;

	CHECK_DEPTH(env, 1, "xlsplit");
	b.b_xf = pop_xforth(env);
	for (i = 0; i < LF_PER_XF; i++)
		PUSH(DS, b.b_lf[(LF_PER_XF - 1) - i]);
}


/*
 * xwflip     ( oct1 -- oct2 )
 */
static void
xwflip(fcode_env_t *env)
{
	union {
		wforth_t b_wf[WF_PER_XF];
		xforth_t b_xf;
	} b, c;
	int i;

	CHECK_DEPTH(env, 1, "xwflip");
	b.b_xf = pop_xforth(env);
	for (i = 0; i < WF_PER_XF; i++)
		c.b_wf[i] = b.b_wf[(WF_PER_XF - 1) - i];
	push_xforth(env, c.b_xf);
}

/*
 * xwflips    ( xaddr len -- )
 */
static void
xwflips(fcode_env_t *env)
{
	fstack_t len, addr;
	int i;

	CHECK_DEPTH(env, 2, "xwflips");
	len = POP(DS);
	addr = POP(DS);
	for (i = 0; i < len; i += sizeof (xforth_t),
	    addr += sizeof (xforth_t)) {
		PUSH(DS, addr);
		unaligned_xfetch(env);
		xwflip(env);
		PUSH(DS, addr);
		unaligned_xstore(env);
	}
}

/*
 * xwsplit    ( o -- w.lo w.2 w.3 w.hi )
 */
static void
xwsplit(fcode_env_t *env)
{
	union {
		wforth_t b_wf[WF_PER_XF];
		xforth_t b_xf;
	} b;
	int i;

	CHECK_DEPTH(env, 1, "xwsplit");
	b.b_xf = pop_xforth(env);
	for (i = 0; i < WF_PER_XF; i++)
		PUSH(DS, b.b_wf[(WF_PER_XF - 1) - i]);
}

#pragma init(_init)

static void
_init(void)
{
	fcode_env_t *env = initial_env;

	ASSERT(env);
	NOTICE;
	P1275(0x241,	0,	"bxjoin",		bxjoin);
	P1275(0x242,	0,	"<l@",			lsfetch);
	P1275(0x243,	0,	"lxjoin",		lxjoin);
	P1275(0x244,	0,	"wxjoin",		wxjoin);
	P1275(0x245,	0,	"x,",			xcomma);
	P1275(0x246,	0,	"x@",			xfetch);
	P1275(0x247,	0,	"x!",			xstore);
	P1275(0x248,	0,	"/x",			slash_x);
	P1275(0x249,	0,	"/x*",			slash_x_times);
	P1275(0x24a,	0,	"xa+",			xa_plus);
	P1275(0x24b,	0,	"xa1+",			xa_one_plus);
	P1275(0x24c,	0,	"xbflip",		xbflip);
	P1275(0x24d,	0,	"xbflips",		xbflips);
	P1275(0x24e,	0,	"xbsplit",		xbsplit);
	P1275(0x24f,	0,	"xlflip",		xlflip);
	P1275(0x250,	0,	"xlflips",		xlflips);
	P1275(0x251,	0,	"xlsplit",		xlsplit);
	P1275(0x252,	0,	"xwflip",		xwflip);
	P1275(0x253,	0,	"xwflips",		xwflips);
	P1275(0x254,	0,	"xwsplit",		xwsplit);

	FORTH(0,		"unaligned-x@",		unaligned_xfetch);
	FORTH(0,		"unaligned-x!",		unaligned_xstore);
}