//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//                  Cycle-Time Calculation for DLX-CPU Core                     //
//                 with Tomasulo Scheduling and Reorderbuffer                   //
//                                                                              //
//                           1998, Daniel Kroening                              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////
//                      abstract data type: a data path                         //
//////////////////////////////////////////////////////////////////////////////////

#include <stdlib.h>
#include <stdio.h>

#include "path.h"

patht& patht::operator+=(const char *circuit)
 {
  if(circuitcount==MAXCIRCUITS) abort();
  circuits[circuitcount].name=circuit;
  circuits[circuitcount].delay=0;
  circuitcount++;

  return *this;
 }

patht& patht::operator+=(int delay)
 {
  if(circuitcount==0)
   {
    printf("Error: no circuit!\n");
    abort();
   }

  circuits[circuitcount-1].delay+=delay;
  acc_delay+=delay;

  return *this;
 }

patht operator+(patht path, int delay)
 {
  if(path.circuitcount==0)
   {
    printf("Error: no circuit!\n");
    abort();
   }

  path.circuits[path.circuitcount-1].delay+=delay;
  path.acc_delay+=delay;

  return path;
 }

patht operator+(patht path, const char *circuit)
 {
  if(path.circuitcount>=MAXCIRCUITS) { printf("%d\n", path.circuitcount); abort(); }
  path.circuits[path.circuitcount].name=circuit;
  path.circuits[path.circuitcount].delay=0;
  path.circuitcount++;

  return path;
 }

void patht::print()
 {
  int i;

  if(circuitcount>0)
   {
    printf("%3d %s\n", 0, circuits[0].name);
 
    for(i=1; i<circuitcount; i++)
     {
      printf("%3d %s\n", circuits[i-1].delay, circuits[i].name);
     }
   }
  
  printf("%3d TOTAL (%d circuits)\n\n", acc_delay, circuitcount);
 }

patht::patht()
 {
  for(int i=0; i<MAXCIRCUITS; i++)
   {
    circuits[i].name=NULL;
    circuits[i].delay=0;
   }

  acc_delay=0;
  circuitcount=0;
 }

patht::patht(const char *name)
 {
  for(int i=0; i<MAXCIRCUITS; i++)
   {
    circuits[i].name=NULL;
    circuits[i].delay=0;
   }

  acc_delay=0;
  circuitcount=1;

  circuits[0].name=name;
  circuits[0].delay=0;
 }

// determine the longest path

patht max(patht a, patht b)
 {
  if(a.acc_delay>=b.acc_delay)
    return a;
  else
    return b;
 }

patht max(patht a, patht b, patht c)
 {
  return max(a, max(b, c));
 }

patht max(patht a, patht b, patht c, patht d)
 {
  return max(a, max(b, c, d));
 }

void pathlistt::add(patht path)
 {
  datat *data;

  data=new datat;
  data->n=list;
  data->path=path;
  list=data;
 }

patht pathlistt::max()
 {
  patht max;
  datat *data;

  max.acc_delay=0;
  max.circuitcount=0;

  data=list;

  while(data!=NULL)
   {
    if(data->path.acc_delay>max.acc_delay)
      max=data->path;

    data=data->n;
   }

  return max;
 }
  
pathlistt::pathlistt()
 {
  list=NULL;
 }

pathlistt::~pathlistt()
 {
  datat *data, *data2;

  data=list;
  while(data!=NULL)
   {
    data2=data;
    data=data->n;
    delete data2;
   }
 }

