OpenBSD-4.6/usr.bin/pcc/pdp10/order.c
/* $OpenBSD: order.c,v 1.3 2007/12/22 13:13:06 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
# include "pass2.h"
int canaddr(NODE *);
/* should we delay the INCR or DECR operation p */
int
deltest(NODE *p)
{
TWORD ty = p->n_type;
return ty == PTR+CHAR || ty == PTR+UCHAR ||
ty == PTR+SHORT || ty == PTR+USHORT;
}
/*
* Check if p can be autoincremented.
* Nothing can be autoincremented on PDP10.
*/
int
autoincr(NODE *p)
{
return 0;
}
/* is it legal to make an OREG or NAME entry which has an
* offset of off, (from a register of r), if the
* resulting thing had type t */
int
notoff(TWORD t, int r, CONSZ off, char *cp)
{
return(0); /* YES */
}
int radebug = 0;
void
offstar(NODE *p, int shape)
{
NODE *q;
if (x2debug)
printf("offstar(%p)\n", p);
if( p->n_op == PLUS || p->n_op == MINUS ){
if( p->n_right->n_op == ICON ){
q = p->n_left;
if (q->n_op != REG)
geninsn(q, INAREG);
p->n_su = -1;
}
}
geninsn(p, INAREG);
}
/*
* findops() failed, see if we can rewrite it to match.
*/
int
setbin(NODE *p)
{
TWORD ty;
NODE *r, *s;
ty = p->n_type;
switch (p->n_op) {
case MINUS:
switch (ty) {
case PTR+CHAR:
case PTR+UCHAR:
case PTR+SHORT:
case PTR+USHORT:
/*
* Must negate the right side and change op to PLUS.
*/
r = p->n_right;
if (r->n_op == ICON) {
r->n_lval = -r->n_lval;
} else {
s = talloc();
s->n_type = r->n_type;
s->n_op = UMINUS;
s->n_left = r;
p->n_right = s;
}
p->n_op = PLUS;
return 1;
}
}
return 0;
}
/* setup for assignment operator */
int
setasg(NODE *p, int cookie)
{
return(0);
}
/* setup for unary operator */
int
setuni(NODE *p, int cookie)
{
return 0;
}
int
special(NODE *p, int shape)
{
switch (shape) {
case SUSHCON:
if (p->n_op == ICON && p->n_name[0] == '\0' &&
(p->n_lval > 0 && p->n_lval <= 0777777))
return 1;
break;
case SNSHCON:
if (p->n_op == ICON && p->n_name[0] == '\0' &&
(p->n_lval < 0 && p->n_lval > -01000000))
return 1;
break;
case SILDB:
if (p->n_op == ASSIGN && p->n_left->n_op == REG &&
p->n_right->n_op == PLUS &&
p->n_right->n_left->n_op == REG &&
p->n_right->n_right->n_op == ICON &&
p->n_right->n_right->n_lval == 1 &&
p->n_right->n_left->n_rval == p->n_left->n_rval)
return 1;
break;
}
return 0;
}
/*
* Set evaluation order of a binary node if it differs from default.
*/
int
setorder(NODE *p)
{
return 0; /* nothing differs on x86 */
}
/*
* Special handling of some instruction register allocation.
*/
struct rspecial *
nspecial(struct optab *q)
{
return 0; /* XXX gcc */
}
/*
* Do the actual conversion of offstar-found OREGs into real OREGs.
*/
void
myormake(NODE *p)
{
if (x2debug)
printf("myormake(%p)\n", p);
}
/*
* set registers in calling conventions live.
*/
int *
livecall(NODE *p)
{
static int r[8], *s = r;
*s = -1;
if (p->n_op == UCALL || p->n_op == UFORTCALL || p->n_op == USTCALL ||
p->n_op == FORTCALL)
return s;
for (p = p->n_right; p->n_op == CM; p = p->n_left) {
if (p->n_right->n_op == ASSIGN &&
p->n_right->n_left->n_op == REG)
*s++ = p->n_right->n_left->n_rval;
}
if (p->n_right->n_op == ASSIGN &&
p->n_right->n_left->n_op == REG)
*s++ = p->n_right->n_left->n_rval;
*s = -1;
return s;
}
/*
* Signal whether the instruction is acceptable for this target.
*/
int
acceptable(struct optab *op)
{
return 1;
}