80 lines
2.2 KiB
C
80 lines
2.2 KiB
C
/****************************************************************
|
|
* *
|
|
* Copyright 2001, 2011 Fidelity Information Services, Inc *
|
|
* *
|
|
* This source code contains the intellectual property *
|
|
* of its copyright holder(s), and is made available *
|
|
* under a license. If you do not know the terms of *
|
|
* the license, please stop and do not read further. *
|
|
* *
|
|
****************************************************************/
|
|
|
|
#include "mdef.h"
|
|
|
|
#include "compiler.h"
|
|
#include "opcode.h"
|
|
#include "mdq.h"
|
|
#include "mvalconv.h"
|
|
#include "hashtab_str.h"
|
|
|
|
GBLREF hash_table_str *complits_hashtab;
|
|
|
|
LITREF octabstruct oc_tab[];
|
|
|
|
void coerce(oprtype *a,unsigned short new_type)
|
|
{
|
|
|
|
mliteral *lit;
|
|
opctype conv, old_op;
|
|
triple *ref, *coerc;
|
|
stringkey litkey;
|
|
ht_ent_str *litent;
|
|
boolean_t litdltd;
|
|
|
|
assert (new_type == OCT_MVAL || new_type == OCT_MINT || new_type == OCT_BOOL);
|
|
assert (a->oprclass == TRIP_REF);
|
|
ref = a->oprval.tref;
|
|
old_op = ref->opcode;
|
|
if (new_type & oc_tab[old_op].octype)
|
|
return;
|
|
if (old_op == OC_COMVAL || old_op == OC_COMINT)
|
|
{
|
|
dqdel(ref,exorder);
|
|
ref = ref->operand[0].oprval.tref;
|
|
old_op = ref->opcode;
|
|
if (new_type & oc_tab[old_op].octype)
|
|
return;
|
|
} else if (OC_LIT == old_op && OCT_MINT == new_type)
|
|
{
|
|
lit = ref->operand[0].oprval.mlit;
|
|
if (!(++lit->rt_addr))
|
|
{ /* completely removing this otherwise unused literal as needs to be an ILIT instead */
|
|
if (NULL != complits_hashtab && NULL != complits_hashtab->base)
|
|
{ /* Deleted entry is in the hash table .. remove it */
|
|
litkey.str = lit->v.str;
|
|
COMPUTE_HASH_STR(&litkey);
|
|
DEBUG_ONLY(litent = lookup_hashtab_str(complits_hashtab, &litkey));
|
|
assert(litent); /* Literal is there .. better be found */
|
|
assert(litent->value == (void *)lit);
|
|
litdltd = delete_hashtab_str(complits_hashtab, &litkey);
|
|
assert(litdltd);
|
|
}
|
|
dqdel(lit, que);
|
|
}
|
|
ref->opcode = OC_ILIT;
|
|
ref->operand[0].oprclass = ILIT_REF;
|
|
ref->operand[0].oprval.ilit = MV_FORCE_INTD(&(lit->v));
|
|
return;
|
|
}
|
|
if (new_type == OCT_BOOL)
|
|
conv = OC_COBOOL;
|
|
else if (new_type == OCT_MINT)
|
|
conv = OC_COMINT;
|
|
else
|
|
conv = OC_COMVAL;
|
|
coerc = newtriple(conv);
|
|
coerc->operand[0] = put_tref(ref);
|
|
*a = put_tref(coerc);
|
|
return;
|
|
}
|