/* $Id: order.c,v 1.8 2007/11/30 23:29:13 gmcgarry 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.
*/
/*
* MIPS port by Jan Enoksson (janeno-1@student.ltu.se) and
* Simon Olsson (simols-1@student.ltu.se) 2005.
*/
#include "pass2.h"
/*
* 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 */
}
/*
* Turn a UMUL-referenced node into OREG.
*/
void
offstar(NODE * p, int shape)
{
if (x2debug)
printf("offstar(%p)\n", p);
if (p->n_op == PLUS || p->n_op == MINUS) {
if (p->n_right->n_op == ICON) {
if (isreg(p->n_left) == 0)
(void)geninsn(p->n_left, INAREG);
/* Converted in ormake() */
return;
}
}
(void)geninsn(p, INAREG);
}
/*
* Do the actual conversion of offstar-found OREGs into real OREGs.
*/
void
myormake(NODE * q)
{
if (x2debug)
printf("myormake(%p)\n", q);
}
/*
* Shape matches for UMUL. Cooperates with offstar().
*/
int
shumul(NODE * p)
{
if (x2debug)
printf("shumul(%p)\n", p);
/* Always turn it into OREG */
return SOREG;
}
/*
* Rewrite operations on binary operators (like +, -, etc...).
* Called as a result of table lookup.
*/
int
setbin(NODE * p)
{
if (x2debug)
printf("setbin(%p)\n", p);
return 0;
}
/* setup for assignment operator */
int
setasg(NODE * p, int cookie)
{
if (x2debug)
printf("setasg(%p)\n", p);
return (0);
}
/* setup for unary operator */
int
setuni(NODE * p, int cookie)
{
return 0;
}
/*
* Special handling of some instruction register allocation.
* - left is the register that left node wants.
* - right is the register that right node wants.
* - res is in which register the result will end up.
* - mask is registers that will be clobbered.
*/
struct rspecial *
nspecial(struct optab * q)
{
switch (q->op) {
case SCONV:
if (q->lshape == SBREG && q->rshape == SCREG) {
static struct rspecial s[] = {
{ NLEFT, A0A1 },
{ NRES, F0 },
{ 0 }
};
return s;
} else if (q->lshape == SCREG && q->rshape == SBREG) {
static struct rspecial s[] = {
{ NLEFT, F0 },
{ NRES, A0A1 },
{ 0 }
};
return s;
} else if (q->lshape == SAREG && q->rshape == SCREG) {
static struct rspecial s[] = {
{ NLEFT, A0 },
{ NRES, F0 },
{ 0 }
};
return s;
}
break;
case MOD:
case DIV:
if (q->lshape == SBREG) {
static struct rspecial s[] = {
{ NLEFT, A0A1 },
{ NRIGHT, A2A3 },
{ NRES, V0V1 },
{ 0 },
};
return s;
} else if (q->lshape == SAREG) {
static struct rspecial s[] = {
{ NLEFT, A0 },
{ NRIGHT, A1 },
{ NRES, V0 },
{ 0 },
};
return s;
}
case RS:
case LS:
if (q->lshape == SBREG) {
static struct rspecial s[] = {
{ NLEFT, A0A1 },
{ NRIGHT, A2 },
{ NRES, V0V1 },
{ 0 },
};
return s;
} else if (q->lshape == SAREG) {
static struct rspecial s[] = {
{ NLEFT, A0 },
{ NRIGHT, A1 },
{ NRES, V0 },
{ 0 },
};
return s;
}
break;
case STARG:
{
static struct rspecial s[] = {
{ NEVER, A0 },
{ NLEFT, A1 },
{ NEVER, A2 },
{ 0 }
};
return s;
}
case STASG:
{
static struct rspecial s[] = {
{ NEVER, A0 },
{ NRIGHT, A1 },
{ NEVER, A2 },
{ 0 }
};
return s;
}
}
comperr("nspecial entry %d: %s", q - table, q->cstring);
return 0; /* XXX gcc */
}
/*
* Set evaluation order of a binary node if it differs from default.
*/
int
setorder(NODE * p)
{
return 0; /* nothing differs */
}
/*
* Set registers "live" at function calls (like arguments in registers).
* This is for liveness analysis of registers.
*/
int *
livecall(NODE *p)
{
static int r[1] = { -1 }; /* Terminate with -1 */
return &r[0];
}
/*
* Signal whether the instruction is acceptable for this target.
*/
int
acceptable(struct optab *op)
{
return 1;
}
syntax highlighted by Code2HTML, v. 0.9.1