tracef(k, "%s", ir_data[ir->opcode].name);
if (ir->size)
tracef(k, "%d", ir->size);
- if (ir->type)
- tracef(k, ".%s",
- ((ir->type == IRT_INT) ? "I" :
- (ir->type == IRT_FLOAT) ? "F" :
- (ir->type == IRT_ANY) ? "*" :
- "?"));
tracef(k, "(");
switch (ir->opcode)
int id;
enum ir_opcode opcode;
int size;
- enum ir_type type;
struct ir* left;
struct ir* right;
union
extern void pass_remove_dead_blocks(struct procedure* proc);
extern void pass_eliminate_trivial_blocks(struct procedure* proc);
extern void pass_instruction_selector(struct procedure* proc);
-extern void pass_type_inference(struct procedure* proc);
extern void procedure_compile(struct procedure* proc);
+++ /dev/null
-#include "mcg.h"
-
-static enum ir_type search_for_type(struct ir* ir, enum ir_type desired)
-{
- const struct ir_data* data;
-
- if (ir->type != IRT_UNSET)
- return ir->type;
-
- data = &ir_data[ir->opcode];
- if (ir->left)
- ir->left->type = search_for_type(ir->left, data->lefttype);
- if (ir->right)
- ir->right->type = search_for_type(ir->right, data->righttype);
-
- switch (data->returntype)
- {
- case IRT_ANY:
- if (desired == IRT_FLOAT)
- ir->opcode++;
- return desired;
-
- case IRT_UNSET:
- assert(!((data->lefttype == IRT_ANY) && (data->righttype == IRT_ANY)));
- if (((data->lefttype == IRT_ANY) && (ir->left->type == IRT_FLOAT)) ||
- ((data->righttype == IRT_ANY) && (ir->right->type == IRT_FLOAT)))
- {
- ir->opcode++;
- return IRT_FLOAT;
- }
- if ((data->lefttype == IRT_ANY) && (ir->left->type == IRT_ANY))
- ir->left->type = IRT_INT;
- if ((data->righttype == IRT_ANY) && (ir->right->type == IRT_ANY))
- ir->right->type = IRT_INT;
- return IRT_INT;
-
- default:
- return data->returntype;
- }
-}
-
-static void push_types_up(struct basicblock* bb)
-{
- int i;
-
- for (i=0; i<bb->irs.count; i++)
- {
- struct ir* ir = bb->irs.item[i];
- ir->type = search_for_type(ir, ir->type);
- }
-}
-
-void pass_type_inference(struct procedure* proc)
-{
- int i;
-
- for (i=0; i<proc->blocks.count; i++)
- push_types_up(proc->blocks.item[i]);
-}
-
-/* vim: set sw=4 ts=4 expandtab : */
-
-
pass_eliminate_trivial_blocks(proc);
pass_remove_dead_blocks(proc);
pass_convert_stack_ops(proc);
- pass_type_inference(proc);
print_blocks('2', proc);
reg = value:CONST4
emit "ldr %reg, #$value"
- cost 4;
+ cost 8;
# Flags:
# S: has size (use in CONST1, CONST2, CONST4, CONST8 forms)
# V: has no size (use in JUMP, CJUMP, RET forms)
-#
-# Types:
-# I, F: integer, float
-# A: any (will be coerced to I or F during IR postprocessing)
-#
-# Any instruction with an A type must be followed by the corresponding F
-# version.
# Simple terminals
-SA.. CONST
-SF.. CONSTF
-SA.. REG
-SF.. REGF
-SI.. LABEL
-SI.. BLOCK
-V... PAIR
-SA.. ANY
-SF.. ANYF
-S... LOCAL
-S... PHI
+S CONST
+S REG
+S LABEL
+S BLOCK
+V PAIR
+S ANY
+S LOCAL
+S PHI
# Magic stack operations
-S.A. PUSH
-S.F. PUSHF
-SA.. POP
-SF.. POPF
+S PUSH
+S POP
#... Memory operations
-SAI. LOAD
-SFI. LOADF
-S.IA STORE
-S.IF STOREF
+S LOAD
+S STORE
# Arithemetic operations
-SIII ADD
-SIII SUB
-SIII MUL
-SIII DIV
-SIII MOD
-SIII NEG
+S ADD
+S SUB
+S MUL
+S DIV
+S MOD
+S NEG
-SFFF ADDF
-SFFF SUBF
-SFFF MULF
-SFFF DIVF
-SFFF NEGF
+S ADDF
+S SUBF
+S MULF
+S DIVF
+S NEGF
-SIII AND
-SIII OR
-SIII EOR
-SIII NOT
+S AND
+S OR
+S EOR
+S NOT
# Conversions
-SIII CII1
-SIII CII2
-SIII CII4
-SIII CII8
+S CII1
+S CII2
+S CII4
+S CII8
-SIII CIU1
-SIII CIU2
-SIII CIU4
-SIII CIU8
+S CIU1
+S CIU2
+S CIU4
+S CIU8
# Tristate comparisons
-SIII COMPARES
-SIII COMPAREU
+S COMPARES
+S COMPAREU
# Boolean comparisons
-SIII IFEQ
-SIII IFLT
-SIII IFLE
+S IFEQ
+S IFLT
+S IFLE
# Procedures
-VI.. CALL
+V CALL
# Flow control --- these never return
-V.I. JUMP
-VIII CJUMPEQ
-VIII CJUMPLT
-VIII CJUMPLE
-V... RET
+V JUMP
+V CJUMPEQ
+V CJUMPLT
+V CJUMPLE
+V RET
# Special
-SI.. STACKADJUST
-SA.. GETRET
-SF.. GETRETF
-S.A. SETRET
-S.F. SETRETF
+S STACKADJUST
+S GETRET
+S SETRET
IRF_SIZED = 1,
};
-enum ir_type
-{
- IRT_UNSET = 0,
- IRT_INT,
- IRT_FLOAT,
- IRT_ANY
-};
-
struct ir_data
{
const char* name;
int flags;
- enum ir_type returntype;
- enum ir_type lefttype;
- enum ir_type righttype;
};
extern const struct ir_data ir_data[];
print "const struct ir_data ir_data[IR__COUNT] = {"
}
- function char_to_type(c) {
- if (c == "I") return "IRT_INT"
- if (c == "F") return "IRT_FLOAT"
- if (c == "A") return "IRT_ANY"
- return "IRT_UNSET"
- }
-
function char_to_flags(c) {
if (c == "S") return "IRF_SIZED"
return "0"
/^ *[^# ]+/ {
printf("\t{ \"%s\", ", $2)
- printf("%s, ", char_to_flags(substr($1, 1, 1)))
- printf("%s, ", char_to_type(substr($1, 2, 1)))
- printf("%s, ", char_to_type(substr($1, 3, 1)))
- printf("%s", char_to_type(substr($1, 4, 1)))
+ printf("%s", char_to_flags(substr($1, 1, 1)))
printf(" },\n")
}