Line 19... |
Line 19... |
|
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <stdarg.h>
|
#include <stdarg.h>
|
#include <assert.h>
|
#include <assert.h>
|
|
#include "sim-config.h"
|
#include "cuc.h"
|
#include "cuc.h"
|
#include "insn.h"
|
#include "insn.h"
|
|
|
/* Checks for memory conflicts between two instructions; returns 1 if detected
|
/* Checks for memory conflicts between two instructions; returns 1 if detected
|
0 - exact; 1 - strong; 2 - weak; 3 - none */
|
0 - exact; 1 - strong; 2 - weak; 3 - none */
|
static int check_memory_conflict (cuc_func *f, cuc_insn *a, cuc_insn *b, int otype)
|
static int check_memory_conflict (cuc_func *f, cuc_insn *a, cuc_insn *b, int otype)
|
{
|
{
|
switch (otype) {
|
switch (otype) {
|
case 0: /* exact */
|
case MO_EXACT: /* exact */
|
case 1: /* strong */
|
case MO_STRONG: /* strong */
|
return 1;
|
return 1;
|
case 2: /* weak */
|
case MO_WEAK: /* weak */
|
assert (a->type & IT_MEMORY);
|
assert (a->type & IT_MEMORY);
|
assert (b->type & IT_MEMORY);
|
assert (b->type & IT_MEMORY);
|
if ((a->opt[1] & OPT_REF) && f->INSN(a->op[1]).index == II_ADD
|
if ((a->opt[1] & OPT_REF) && f->INSN(a->op[1]).index == II_ADD
|
&&(b->opt[1] & OPT_REF) && f->INSN(b->op[1]).index == II_ADD) {
|
&&(b->opt[1] & OPT_REF) && f->INSN(b->op[1]).index == II_ADD) {
|
int aw, bw;
|
int aw, bw;
|
Line 49... |
Line 50... |
/* Check if they overlap */
|
/* Check if they overlap */
|
if (a->op[2] >= b->op[2] && a->op[2] < b->op[2] + bw) return 1;
|
if (a->op[2] >= b->op[2] && a->op[2] < b->op[2] + bw) return 1;
|
if (b->op[2] >= a->op[2] && b->op[2] < a->op[2] + aw) return 1;
|
if (b->op[2] >= a->op[2] && b->op[2] < a->op[2] + aw) return 1;
|
return 0;
|
return 0;
|
} else return 1;
|
} else return 1;
|
case 3: /* none */
|
case MO_NONE: /* none */
|
return 0;
|
return 0;
|
default:
|
default:
|
assert (0);
|
assert (0);
|
}
|
}
|
return 1;
|
return 1;
|
Line 110... |
Line 111... |
for (b = 0; b < f->num_bb; b++) {
|
for (b = 0; b < f->num_bb; b++) {
|
cuc_insn *insn = f->bb[b].insn;
|
cuc_insn *insn = f->bb[b].insn;
|
for (i = 0; i < f->bb[b].ninsn; i++)
|
for (i = 0; i < f->bb[b].ninsn; i++)
|
if (insn[i].type & IT_MEMORY) {
|
if (insn[i].type & IT_MEMORY) {
|
f->msched[f->nmsched++] = REF (b, i);
|
f->msched[f->nmsched++] = REF (b, i);
|
if (otype == 2 || otype == 3) insn[i].type |= IT_FLAG1; /* mark unscheduled */
|
if (otype == MO_NONE || otype == MO_WEAK) insn[i].type |= IT_FLAG1; /* mark unscheduled */
|
}
|
}
|
}
|
}
|
#if 0
|
#if 0
|
for (i = 0; i < f->nmsched; i++)
|
for (i = 0; i < f->nmsched; i++)
|
printf ("[%i]%i%c ", f->msched[i], f->mtype[i] & MT_WIDTH, (f->mtype[i] & MT_BURST) ? (f->mtype[i] & MT_BURSTE) ? 'E' : 'B' : ' ');
|
printf ("[%i]%i%c ", f->msched[i], f->mtype[i] & MT_WIDTH, (f->mtype[i] & MT_BURST) ? (f->mtype[i] & MT_BURSTE) ? 'E' : 'B' : ' ');
|
Line 122... |
Line 123... |
#endif
|
#endif
|
|
|
/* We can reorder just more loose types
|
/* We can reorder just more loose types
|
We assume, that memory accesses are currently in valid (but not neccesserly)
|
We assume, that memory accesses are currently in valid (but not neccesserly)
|
optimal order */
|
optimal order */
|
if (otype == 2 || otype == 3) {
|
if (otype == MO_WEAK || otype == MO_NONE) {
|
for (i = 0; i < f->nmsched; i++) {
|
for (i = 0; i < f->nmsched; i++) {
|
int best = i;
|
int best = i;
|
int tmp;
|
int tmp;
|
for (j = i + 1; j < f->nmsched; j++) if (REF_BB(f->msched[j]) == REF_BB(f->msched[best])) {
|
for (j = i + 1; j < f->nmsched; j++) if (REF_BB(f->msched[j]) == REF_BB(f->msched[best])) {
|
if (mem_ordering_cmp (f, &f->INSN (f->msched[j]), &f->INSN(f->msched[best]))) {
|
if (mem_ordering_cmp (f, &f->INSN (f->msched[j]), &f->INSN(f->msched[best]))) {
|
Line 162... |
Line 163... |
f->mtype[i] = !II_IS_LOAD(a->index) ? MT_WRITE : 0;
|
f->mtype[i] = !II_IS_LOAD(a->index) ? MT_WRITE : 0;
|
f->mtype[i] |= II_MEM_WIDTH (a->index);
|
f->mtype[i] |= II_MEM_WIDTH (a->index);
|
if (a->type & IT_SIGNED) f->mtype[i] |= MT_SIGNED;
|
if (a->type & IT_SIGNED) f->mtype[i] |= MT_SIGNED;
|
}
|
}
|
|
|
if (enable_bursts) {
|
if (config.cuc.enable_bursts) {
|
//printf ("\n");
|
//printf ("\n");
|
for (i = 1; i < f->nmsched; i++) {
|
for (i = 1; i < f->nmsched; i++) {
|
cuc_insn *a = &f->INSN(f->msched[i - 1]);
|
cuc_insn *a = &f->INSN(f->msched[i - 1]);
|
cuc_insn *b = &f->INSN(f->msched[i]);
|
cuc_insn *b = &f->INSN(f->msched[i]);
|
int aw = f->mtype[i - 1] & MT_WIDTH;
|
int aw = f->mtype[i - 1] & MT_WIDTH;
|