fis-gtm/sr_port/coerce.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;
}