2008-02-19 18:06:52 +00:00
/* Copyright (c) 2008, Avian Contributors
Permission to use , copy , modify , and / or distribute this software
for any purpose with or without fee is hereby granted , provided
that the above copyright notice and this permission notice appear
in all copies .
There is NO WARRANTY for this software . See license . txt for
details . */
2008-02-12 00:20:32 +00:00
# include "compiler.h"
2008-02-11 17:21:41 +00:00
# include "assembler.h"
2007-12-08 23:22:13 +00:00
using namespace vm ;
namespace {
2008-10-06 00:50:59 +00:00
const bool DebugAppend = true ;
const bool DebugCompile = true ;
2008-04-27 20:15:18 +00:00
const bool DebugStack = false ;
2008-10-12 00:23:08 +00:00
const bool DebugRegisters = false ;
const bool DebugFrameIndexes = false ;
2008-04-19 21:52:45 +00:00
2008-08-23 18:04:36 +00:00
const int AnyFrameIndex = - 2 ;
const int NoFrameIndex = - 1 ;
2008-02-11 17:21:41 +00:00
class Context ;
2008-04-16 20:58:21 +00:00
class Value ;
2008-04-17 22:07:32 +00:00
class Stack ;
class Site ;
2008-10-12 00:23:08 +00:00
class ConstantSite ;
class AddressSite ;
2008-05-15 23:19:23 +00:00
class RegisterSite ;
2008-09-28 21:56:12 +00:00
class MemorySite ;
2008-04-17 22:07:32 +00:00
class Event ;
2008-04-18 03:47:42 +00:00
class PushEvent ;
2008-04-18 00:39:41 +00:00
class Read ;
2008-09-13 21:09:26 +00:00
class MultiRead ;
2008-09-22 14:28:18 +00:00
class StubRead ;
2008-08-30 20:12:27 +00:00
class Block ;
2008-11-01 22:16:18 +00:00
class Snapshot ;
2007-12-09 22:45:43 +00:00
2008-04-16 20:58:21 +00:00
void NO_RETURN abort ( Context * ) ;
2008-03-15 23:54:20 +00:00
2008-04-17 22:07:32 +00:00
void
2008-08-16 17:45:36 +00:00
apply ( Context * c , UnaryOperation op ,
unsigned s1Size , Site * s1 ) ;
2008-04-17 22:07:32 +00:00
void
2008-08-16 17:45:36 +00:00
apply ( Context * c , BinaryOperation op ,
unsigned s1Size , Site * s1 ,
unsigned s2Size , Site * s2 ) ;
void
apply ( Context * c , TernaryOperation op ,
unsigned s1Size , Site * s1 ,
unsigned s2Size , Site * s2 ,
unsigned s3Size , Site * s3 ) ;
2008-04-17 22:07:32 +00:00
2008-06-11 00:17:44 +00:00
enum ConstantCompare {
CompareNone ,
CompareLess ,
CompareGreater ,
CompareEqual
} ;
2008-08-23 18:04:36 +00:00
class Cell {
public :
Cell ( Cell * next , void * value ) : next ( next ) , value ( value ) { }
Cell * next ;
void * value ;
} ;
2008-09-24 00:01:42 +00:00
class Local {
public :
Value * value ;
2008-11-01 19:14:13 +00:00
unsigned sizeInBytes ;
2008-09-24 00:01:42 +00:00
} ;
2008-04-16 20:58:21 +00:00
class Site {
public :
Site ( ) : next ( 0 ) { }
virtual ~ Site ( ) { }
2008-05-12 13:54:47 +00:00
virtual Site * readTarget ( Context * , Read * ) { return this ; }
2008-04-17 02:55:38 +00:00
2008-10-04 17:26:35 +00:00
virtual void toString ( Context * , char * , unsigned ) = 0 ;
2008-04-16 20:58:21 +00:00
virtual unsigned copyCost ( Context * , Site * ) = 0 ;
2008-08-23 18:04:36 +00:00
virtual bool match ( Context * , uint8_t , uint64_t , int ) = 0 ;
2008-04-16 20:58:21 +00:00
2008-09-24 00:01:42 +00:00
virtual void acquire ( Context * , Stack * , Local * , unsigned , Value * ) { }
2008-04-17 02:55:38 +00:00
2008-04-19 00:19:45 +00:00
virtual void release ( Context * ) { }
2008-05-12 13:54:47 +00:00
virtual void freeze ( Context * ) { }
virtual void thaw ( Context * ) { }
2008-10-15 00:45:31 +00:00
virtual bool usesRegister ( Context * , int ) { return false ; }
2008-04-17 22:07:32 +00:00
virtual OperandType type ( Context * ) = 0 ;
2008-04-16 20:58:21 +00:00
2008-04-17 02:55:38 +00:00
virtual Assembler : : Operand * asAssemblerOperand ( Context * ) = 0 ;
2008-04-16 20:58:21 +00:00
2008-10-12 00:23:08 +00:00
virtual Site * copy ( Context * ) = 0 ;
2008-10-04 17:26:35 +00:00
2008-04-16 20:58:21 +00:00
Site * next ;
} ;
2008-08-23 18:04:36 +00:00
class Stack : public Compiler : : StackElement {
2008-04-17 22:07:32 +00:00
public :
2008-11-01 19:14:13 +00:00
Stack ( unsigned index , unsigned sizeInWords , Value * value , Stack * next ) :
index ( index ) , sizeInWords ( sizeInWords ) , paddingInWords ( 0 ) , value ( value ) ,
next ( next )
2008-04-17 22:07:32 +00:00
{ }
unsigned index ;
2008-11-01 19:14:13 +00:00
unsigned sizeInWords ;
unsigned paddingInWords ;
2008-07-05 20:21:13 +00:00
Value * value ;
2008-04-17 22:07:32 +00:00
Stack * next ;
} ;
2008-09-22 14:28:18 +00:00
class MultiReadPair {
public :
Value * value ;
MultiRead * read ;
} ;
2008-10-14 00:18:18 +00:00
class ForkState : public Compiler : : State {
2008-04-17 22:07:32 +00:00
public :
2008-10-14 00:18:18 +00:00
ForkState ( Stack * stack , Local * locals , Event * predecessor ,
unsigned logicalIp ) :
2008-04-27 21:58:29 +00:00
stack ( stack ) ,
2008-07-05 20:21:13 +00:00
locals ( locals ) ,
2008-09-20 23:42:46 +00:00
predecessor ( predecessor ) ,
logicalIp ( logicalIp ) ,
readCount ( 0 )
2008-04-17 22:07:32 +00:00
{ }
Stack * stack ;
2008-09-24 00:01:42 +00:00
Local * locals ;
2008-09-20 23:42:46 +00:00
Event * predecessor ;
unsigned logicalIp ;
unsigned readCount ;
2008-09-22 00:58:54 +00:00
MultiReadPair reads [ 0 ] ;
2008-04-17 22:07:32 +00:00
} ;
class LogicalInstruction {
public :
2008-09-24 00:01:42 +00:00
LogicalInstruction ( int index , Stack * stack , Local * locals ) :
2008-09-15 02:28:42 +00:00
firstEvent ( 0 ) , lastEvent ( 0 ) , immediatePredecessor ( 0 ) , stack ( stack ) ,
locals ( locals ) , machineOffset ( 0 ) , index ( index )
2008-09-07 20:12:11 +00:00
{ }
2008-09-07 01:37:12 +00:00
2008-04-19 07:03:59 +00:00
Event * firstEvent ;
2008-04-17 22:07:32 +00:00
Event * lastEvent ;
2008-04-20 19:35:36 +00:00
LogicalInstruction * immediatePredecessor ;
Stack * stack ;
2008-09-24 00:01:42 +00:00
Local * locals ;
2008-09-09 00:31:19 +00:00
Promise * machineOffset ;
2008-08-30 20:12:27 +00:00
int index ;
2008-04-17 22:07:32 +00:00
} ;
class Register {
public :
2008-05-12 13:54:47 +00:00
Register ( int number ) :
2008-05-15 23:19:23 +00:00
value ( 0 ) , site ( 0 ) , number ( number ) , size ( 0 ) , refCount ( 0 ) ,
2008-09-28 21:56:12 +00:00
freezeCount ( 0 ) , reserved ( false )
2008-05-12 13:54:47 +00:00
{ }
2008-04-17 22:07:32 +00:00
Value * value ;
2008-05-15 23:19:23 +00:00
RegisterSite * site ;
2008-05-12 13:54:47 +00:00
int number ;
2008-04-17 22:07:32 +00:00
unsigned size ;
2008-04-20 00:43:12 +00:00
unsigned refCount ;
2008-05-12 13:54:47 +00:00
unsigned freezeCount ;
2008-04-17 22:07:32 +00:00
bool reserved ;
2008-09-28 21:56:12 +00:00
} ;
class FrameResource {
public :
Value * value ;
MemorySite * site ;
unsigned size ;
2008-04-17 22:07:32 +00:00
} ;
class ConstantPoolNode {
public :
ConstantPoolNode ( Promise * promise ) : promise ( promise ) , next ( 0 ) { }
Promise * promise ;
ConstantPoolNode * next ;
} ;
class Read {
public :
2008-09-24 00:01:42 +00:00
Read ( unsigned size ) :
value ( 0 ) , event ( 0 ) , eventNext ( 0 ) , size ( size )
2008-04-17 22:07:32 +00:00
{ }
2008-07-05 20:21:13 +00:00
2008-09-06 21:25:41 +00:00
virtual ~ Read ( ) { }
2008-07-05 20:21:13 +00:00
virtual Site * pickSite ( Context * c , Value * v ) = 0 ;
virtual Site * allocateSite ( Context * c ) = 0 ;
2008-09-15 02:28:42 +00:00
virtual bool intersect ( uint8_t * typeMask , uint64_t * registerMask ,
2008-07-05 20:21:13 +00:00
int * frameIndex ) = 0 ;
virtual bool valid ( ) = 0 ;
2008-08-30 20:12:27 +00:00
2008-09-13 21:09:26 +00:00
virtual void append ( Context * c , Read * r ) = 0 ;
2008-09-15 02:28:42 +00:00
virtual Read * next ( Context * c ) = 0 ;
2008-08-28 22:43:35 +00:00
Value * value ;
Event * event ;
Read * eventNext ;
2008-09-24 00:01:42 +00:00
unsigned size ;
2008-04-17 22:07:32 +00:00
} ;
2008-08-28 22:43:35 +00:00
int
intersectFrameIndexes ( int a , int b )
{
if ( a = = NoFrameIndex or b = = NoFrameIndex ) return NoFrameIndex ;
if ( a = = AnyFrameIndex ) return b ;
if ( b = = AnyFrameIndex ) return a ;
if ( a = = b ) return a ;
return NoFrameIndex ;
}
2008-04-17 22:07:32 +00:00
class Value : public Compiler : : Operand {
public :
2008-04-26 20:56:03 +00:00
Value ( Site * site , Site * target ) :
2008-11-01 19:14:13 +00:00
reads ( 0 ) , lastRead ( 0 ) , sites ( site ) , source ( 0 ) , target ( target ) , buddy ( this ) ,
local ( false )
2008-04-17 22:07:32 +00:00
{ }
2008-09-13 21:09:26 +00:00
virtual ~ Value ( ) { }
virtual void addPredecessor ( Context * , Event * ) { }
2008-04-17 22:07:32 +00:00
Read * reads ;
Read * lastRead ;
Site * sites ;
Site * source ;
2008-04-19 20:41:31 +00:00
Site * target ;
2008-11-01 19:14:13 +00:00
Value * buddy ;
bool local ;
2008-04-17 22:07:32 +00:00
} ;
2008-07-05 20:21:13 +00:00
enum Pass {
ScanPass ,
CompilePass
} ;
2008-04-17 22:07:32 +00:00
class Context {
public :
2008-05-31 22:14:27 +00:00
Context ( System * system , Assembler * assembler , Zone * zone ,
Compiler : : Client * client ) :
2008-04-17 22:07:32 +00:00
system ( system ) ,
assembler ( assembler ) ,
2008-08-23 18:04:36 +00:00
arch ( assembler - > arch ( ) ) ,
2008-04-17 22:07:32 +00:00
zone ( zone ) ,
2008-05-31 22:14:27 +00:00
client ( client ) ,
2008-09-13 21:09:26 +00:00
stack ( 0 ) ,
locals ( 0 ) ,
2008-09-20 23:42:46 +00:00
predecessor ( 0 ) ,
2008-04-17 22:07:32 +00:00
logicalCode ( 0 ) ,
2008-05-12 13:54:47 +00:00
registers
( static_cast < Register * * >
2008-08-23 18:04:36 +00:00
( zone - > allocate ( sizeof ( Register * ) * arch - > registerCount ( ) ) ) ) ,
2008-09-28 21:56:12 +00:00
frameResources ( 0 ) ,
2008-04-17 22:07:32 +00:00
firstConstant ( 0 ) ,
lastConstant ( 0 ) ,
2008-08-30 20:12:27 +00:00
machineCode ( 0 ) ,
firstEvent ( 0 ) ,
2008-09-07 01:37:12 +00:00
lastEvent ( 0 ) ,
2008-10-14 00:18:18 +00:00
forkState ( 0 ) ,
2008-08-30 20:12:27 +00:00
logicalIp ( - 1 ) ,
2008-04-17 22:07:32 +00:00
constantCount ( 0 ) ,
2008-08-30 20:12:27 +00:00
logicalCodeLength ( 0 ) ,
parameterFootprint ( 0 ) ,
localFootprint ( 0 ) ,
2008-09-23 21:18:41 +00:00
machineCodeSize ( 0 ) ,
2008-09-28 19:00:52 +00:00
alignedFrameSize ( 0 ) ,
2008-09-27 22:01:39 +00:00
availableRegisterCount ( arch - > registerCount ( ) ) ,
2008-07-05 20:21:13 +00:00
constantCompare ( CompareNone ) ,
2008-08-30 20:12:27 +00:00
pass ( ScanPass )
2008-04-17 22:07:32 +00:00
{
2008-08-23 18:04:36 +00:00
for ( unsigned i = 0 ; i < arch - > registerCount ( ) ; + + i ) {
2008-05-12 13:54:47 +00:00
registers [ i ] = new ( zone - > allocate ( sizeof ( Register ) ) ) Register ( i ) ;
2008-09-27 22:01:39 +00:00
if ( arch - > reserved ( i ) ) {
registers [ i ] - > reserved = true ;
- - availableRegisterCount ;
}
2008-05-12 13:54:47 +00:00
}
2008-04-17 22:07:32 +00:00
}
System * system ;
Assembler * assembler ;
2008-08-23 18:04:36 +00:00
Assembler : : Architecture * arch ;
2008-04-17 22:07:32 +00:00
Zone * zone ;
2008-05-31 22:14:27 +00:00
Compiler : : Client * client ;
2008-09-13 21:09:26 +00:00
Stack * stack ;
2008-09-24 00:01:42 +00:00
Local * locals ;
2008-09-20 23:42:46 +00:00
Event * predecessor ;
2008-08-16 17:45:36 +00:00
LogicalInstruction * * logicalCode ;
2008-05-12 13:54:47 +00:00
Register * * registers ;
2008-09-28 21:56:12 +00:00
FrameResource * frameResources ;
2008-04-17 22:07:32 +00:00
ConstantPoolNode * firstConstant ;
ConstantPoolNode * lastConstant ;
2008-08-30 20:12:27 +00:00
uint8_t * machineCode ;
Event * firstEvent ;
2008-09-07 01:37:12 +00:00
Event * lastEvent ;
2008-10-14 00:18:18 +00:00
ForkState * forkState ;
2008-08-30 20:12:27 +00:00
int logicalIp ;
2008-04-17 22:07:32 +00:00
unsigned constantCount ;
2008-08-30 20:12:27 +00:00
unsigned logicalCodeLength ;
unsigned parameterFootprint ;
unsigned localFootprint ;
2008-09-23 21:18:41 +00:00
unsigned machineCodeSize ;
2008-09-28 19:00:52 +00:00
unsigned alignedFrameSize ;
2008-09-27 22:01:39 +00:00
unsigned availableRegisterCount ;
2008-06-11 00:17:44 +00:00
ConstantCompare constantCompare ;
2008-07-05 20:21:13 +00:00
Pass pass ;
2008-04-17 22:07:32 +00:00
} ;
2008-04-18 17:00:55 +00:00
class PoolPromise : public Promise {
public :
PoolPromise ( Context * c , int key ) : c ( c ) , key ( key ) { }
virtual int64_t value ( ) {
if ( resolved ( ) ) {
return reinterpret_cast < intptr_t >
2008-09-23 21:18:41 +00:00
( c - > machineCode + pad ( c - > machineCodeSize ) + ( key * BytesPerWord ) ) ;
2008-04-18 17:00:55 +00:00
}
abort ( c ) ;
}
virtual bool resolved ( ) {
return c - > machineCode ! = 0 ;
}
Context * c ;
int key ;
} ;
class CodePromise : public Promise {
public :
2008-08-30 20:12:27 +00:00
CodePromise ( Context * c , CodePromise * next ) :
c ( c ) , offset ( 0 ) , next ( next )
{ }
2008-04-18 17:00:55 +00:00
2008-09-09 00:31:19 +00:00
CodePromise ( Context * c , Promise * offset ) :
2008-08-30 20:12:27 +00:00
c ( c ) , offset ( offset ) , next ( 0 )
{ }
2008-04-18 17:00:55 +00:00
virtual int64_t value ( ) {
if ( resolved ( ) ) {
2008-08-30 20:12:27 +00:00
return reinterpret_cast < intptr_t > ( c - > machineCode + offset - > value ( ) ) ;
2008-04-18 17:00:55 +00:00
}
abort ( c ) ;
}
virtual bool resolved ( ) {
2008-08-30 20:12:27 +00:00
return c - > machineCode ! = 0 and offset and offset - > resolved ( ) ;
2008-04-18 17:00:55 +00:00
}
Context * c ;
2008-09-09 00:31:19 +00:00
Promise * offset ;
2008-04-18 17:00:55 +00:00
CodePromise * next ;
} ;
2008-09-07 20:12:11 +00:00
unsigned
machineOffset ( Context * c , int logicalIp )
{
2008-09-22 14:28:18 +00:00
return c - > logicalCode [ logicalIp ] - > machineOffset - > value ( ) ;
2008-09-07 20:12:11 +00:00
}
2008-04-18 17:00:55 +00:00
class IpPromise : public Promise {
public :
IpPromise ( Context * c , int logicalIp ) :
c ( c ) ,
logicalIp ( logicalIp )
{ }
virtual int64_t value ( ) {
if ( resolved ( ) ) {
return reinterpret_cast < intptr_t >
2008-09-07 20:12:11 +00:00
( c - > machineCode + machineOffset ( c , logicalIp ) ) ;
2008-04-18 17:00:55 +00:00
}
abort ( c ) ;
}
virtual bool resolved ( ) {
return c - > machineCode ! = 0 ;
}
Context * c ;
int logicalIp ;
} ;
inline void NO_RETURN
abort ( Context * c )
{
abort ( c - > system ) ;
}
# ifndef NDEBUG
inline void
assert ( Context * c , bool v )
{
assert ( c - > system , v ) ;
}
# endif // not NDEBUG
inline void
expect ( Context * c , bool v )
{
expect ( c - > system , v ) ;
}
2008-09-07 20:12:11 +00:00
Cell *
cons ( Context * c , void * value , Cell * next )
{
return new ( c - > zone - > allocate ( sizeof ( Cell ) ) ) Cell ( next , value ) ;
}
2008-09-13 21:09:26 +00:00
Cell *
append ( Context * c , Cell * first , Cell * second )
{
if ( first ) {
if ( second ) {
Cell * start = cons ( c , first - > value , second ) ;
Cell * end = start ;
for ( Cell * cell = first - > next ; cell ; cell = cell - > next ) {
Cell * n = cons ( c , cell - > value , second ) ;
end - > next = n ;
end = n ;
}
return start ;
} else {
return first ;
}
} else {
return second ;
}
}
2008-10-15 00:45:31 +00:00
Cell *
reverseDestroy ( Cell * cell )
{
Cell * previous = 0 ;
while ( cell ) {
Cell * next = cell - > next ;
cell - > next = previous ;
previous = cell ;
cell = next ;
}
return previous ;
}
2008-09-22 14:28:18 +00:00
class StubReadPair {
public :
Value * value ;
StubRead * read ;
} ;
2008-10-14 00:18:18 +00:00
class JunctionState {
2008-04-18 17:00:55 +00:00
public :
2008-10-14 00:18:18 +00:00
JunctionState ( ) : readCount ( 0 ) { }
2008-04-18 17:00:55 +00:00
2008-10-14 00:18:18 +00:00
unsigned readCount ;
StubReadPair reads [ 0 ] ;
} ;
2008-09-07 01:37:12 +00:00
2008-10-14 00:18:18 +00:00
class Link {
public :
Link ( Event * predecessor , Link * nextPredecessor , Event * successor ,
Link * nextSuccessor , ForkState * forkState ) :
predecessor ( predecessor ) , nextPredecessor ( nextPredecessor ) ,
successor ( successor ) , nextSuccessor ( nextSuccessor ) , forkState ( forkState ) ,
junctionState ( 0 )
{ }
2008-09-15 02:28:42 +00:00
2008-10-14 00:18:18 +00:00
Event * predecessor ;
Link * nextPredecessor ;
Event * successor ;
Link * nextSuccessor ;
ForkState * forkState ;
JunctionState * junctionState ;
} ;
2008-09-15 02:28:42 +00:00
2008-10-14 00:18:18 +00:00
Link *
link ( Context * c , Event * predecessor , Link * nextPredecessor , Event * successor ,
Link * nextSuccessor , ForkState * forkState )
{
return new ( c - > zone - > allocate ( sizeof ( Link ) ) ) Link
( predecessor , nextPredecessor , successor , nextSuccessor , forkState ) ;
}
2008-04-18 17:00:55 +00:00
2008-10-14 00:18:18 +00:00
unsigned
countPredecessors ( Link * link )
{
unsigned c = 0 ;
for ( ; link ; link = link - > nextPredecessor ) + + c ;
return c ;
}
Link *
lastPredecessor ( Link * link )
{
while ( link - > nextPredecessor ) link = link - > nextPredecessor ;
return link ;
}
unsigned
countSuccessors ( Link * link )
{
unsigned c = 0 ;
for ( ; link ; link = link - > nextSuccessor ) + + c ;
return c ;
}
class Event {
public :
Event ( Context * c ) :
next ( 0 ) , stackBefore ( c - > stack ) , localsBefore ( c - > locals ) ,
stackAfter ( 0 ) , localsAfter ( 0 ) , promises ( 0 ) , reads ( 0 ) ,
2008-11-01 22:16:18 +00:00
junctionSites ( 0 ) , snapshots ( 0 ) , predecessors ( 0 ) , successors ( 0 ) ,
2008-10-15 00:45:31 +00:00
visitLinks ( 0 ) , block ( 0 ) , logicalInstruction ( c - > logicalCode [ c - > logicalIp ] ) ,
2008-10-14 00:18:18 +00:00
readCount ( 0 )
{ }
2008-04-18 17:00:55 +00:00
virtual ~ Event ( ) { }
2008-09-15 02:28:42 +00:00
virtual const char * name ( ) = 0 ;
2008-04-18 17:00:55 +00:00
2008-10-14 00:18:18 +00:00
virtual void compile ( Context * c ) = 0 ;
2008-08-30 20:12:27 +00:00
2008-10-08 00:08:13 +00:00
virtual bool isBranch ( ) { return false ; }
2008-04-18 17:00:55 +00:00
Event * next ;
2008-10-04 17:26:35 +00:00
Stack * stackBefore ;
Local * localsBefore ;
Stack * stackAfter ;
Local * localsAfter ;
2008-04-18 17:00:55 +00:00
CodePromise * promises ;
Read * reads ;
2008-08-30 20:12:27 +00:00
Site * * junctionSites ;
2008-11-01 22:16:18 +00:00
Snapshot * snapshots ;
2008-10-14 00:18:18 +00:00
Link * predecessors ;
Link * successors ;
2008-10-15 00:45:31 +00:00
Cell * visitLinks ;
2008-08-30 20:12:27 +00:00
Block * block ;
LogicalInstruction * logicalInstruction ;
2008-05-15 14:29:19 +00:00
unsigned readCount ;
2008-04-18 17:00:55 +00:00
} ;
2008-05-19 04:31:52 +00:00
int
2008-11-01 19:14:13 +00:00
frameIndex ( Context * c , int index , unsigned sizeInWords )
2008-05-19 04:31:52 +00:00
{
2008-11-01 19:14:13 +00:00
return c - > alignedFrameSize + c - > parameterFootprint - index - sizeInWords ;
2008-05-19 04:31:52 +00:00
}
2008-10-25 02:12:02 +00:00
unsigned
frameIndexToOffset ( Context * c , unsigned frameIndex )
2008-09-28 21:56:12 +00:00
{
2008-10-25 02:12:02 +00:00
return ( ( frameIndex > = c - > alignedFrameSize ) ?
( frameIndex
+ ( c - > arch - > frameFooterSize ( ) * 2 )
+ c - > arch - > frameHeaderSize ( ) ) :
( frameIndex
+ c - > arch - > frameFooterSize ( ) ) ) * BytesPerWord ;
}
2008-09-28 21:56:12 +00:00
2008-10-25 02:12:02 +00:00
unsigned
offsetToFrameIndex ( Context * c , unsigned offset )
{
unsigned normalizedOffset = offset / BytesPerWord ;
2008-09-28 21:56:12 +00:00
2008-10-25 02:12:02 +00:00
return ( ( normalizedOffset
> = c - > alignedFrameSize
+ c - > arch - > frameFooterSize ( ) ) ?
( normalizedOffset
- ( c - > arch - > frameFooterSize ( ) * 2 )
- c - > arch - > frameHeaderSize ( ) ) :
( normalizedOffset
- c - > arch - > frameFooterSize ( ) ) ) ;
2008-09-28 21:56:12 +00:00
}
2008-11-01 19:14:13 +00:00
class FrameIterator {
public :
class Element {
public :
Element ( Value * value , unsigned localIndex , unsigned sizeInBytes ) :
value ( value ) , localIndex ( localIndex ) , sizeInBytes ( sizeInBytes )
{ }
Value * const value ;
const unsigned localIndex ;
const unsigned sizeInBytes ;
} ;
FrameIterator ( Context * c , Stack * stack , Local * locals ) :
stack ( stack ) , locals ( locals ) , localIndex ( c - > localFootprint - 1 )
{ }
bool hasMore ( ) {
while ( localIndex > = 0 and locals [ localIndex ] . value = = 0 ) - - localIndex ;
return stack ! = 0 or localIndex > = 0 ;
}
Element next ( Context * c ) {
Value * v ;
unsigned li ;
unsigned sizeInBytes ;
if ( stack ) {
Stack * s = stack ;
v = s - > value ;
li = s - > index + c - > localFootprint ;
sizeInBytes = s - > sizeInWords * BytesPerWord ;
stack = stack - > next ;
} else {
Local * l = locals + localIndex ;
v = l - > value ;
li = localIndex ;
sizeInBytes = l - > sizeInBytes ;
- - localIndex ;
}
return Element ( v , li , sizeInBytes ) ;
}
Stack * stack ;
Local * locals ;
int localIndex ;
} ;
int
frameIndex ( Context * c , FrameIterator : : Element * element )
{
return frameIndex
( c , element - > localIndex , ceiling ( element - > sizeInBytes , BytesPerWord ) ) ; ;
}
class SiteIterator {
public :
SiteIterator ( Value * v ) :
originalValue ( v ) ,
currentValue ( v ) ,
next_ ( findNext ( & ( v - > sites ) ) ) ,
previous ( 0 )
{ }
Site * * findNext ( Site * * p ) {
if ( * p ) {
return p ;
} else {
for ( Value * v = currentValue - > buddy ;
v ! = originalValue ;
v = v - > buddy )
{
if ( v - > sites ) {
currentValue = v ;
return & ( v - > sites ) ;
}
}
return 0 ;
}
}
bool hasMore ( ) {
if ( previous ) {
next_ = findNext ( & ( ( * previous ) - > next ) ) ;
previous = 0 ;
}
return next_ ! = 0 ;
}
Site * next ( ) {
previous = next_ ;
return * previous ;
}
void remove ( Context * c ) {
( * previous ) - > release ( c ) ;
* previous = ( * previous ) - > next ;
next_ = findNext ( previous ) ;
previous = 0 ;
}
Value * originalValue ;
Value * currentValue ;
Site * * next_ ;
Site * * previous ;
} ;
2008-11-01 22:16:18 +00:00
bool
hasMoreThanOneSite ( Value * v )
{
SiteIterator it ( v ) ;
if ( it . hasMore ( ) ) {
it . next ( ) ;
return it . hasMore ( ) ;
} else {
return false ;
}
}
bool
hasSite ( Value * v )
{
SiteIterator it ( v ) ;
return it . hasMore ( ) ;
}
2008-04-18 00:39:41 +00:00
bool
findSite ( Context * , Value * v , Site * site )
{
for ( Site * s = v - > sites ; s ; s = s - > next ) {
if ( s = = site ) return true ;
}
return false ;
}
2008-05-12 13:54:47 +00:00
void
2008-09-24 00:01:42 +00:00
addSite ( Context * c , Stack * stack , Local * locals , unsigned size , Value * v ,
2008-07-17 23:34:38 +00:00
Site * s )
2008-04-19 00:19:45 +00:00
{
if ( not findSite ( c , v , s ) ) {
2008-04-29 16:25:20 +00:00
// fprintf(stderr, "add site %p (%d) to %p\n", s, s->type(c), v);
2008-07-17 23:34:38 +00:00
s - > acquire ( c , stack , locals , size , v ) ;
2008-05-12 13:54:47 +00:00
s - > next = v - > sites ;
v - > sites = s ;
2008-04-19 00:19:45 +00:00
}
}
2008-04-18 00:39:41 +00:00
void
2008-04-19 07:03:59 +00:00
removeSite ( Context * c , Value * v , Site * s )
2008-04-18 00:39:41 +00:00
{
2008-11-01 19:14:13 +00:00
for ( SiteIterator it ( v ) ; it . hasMore ( ) ; ) {
if ( s = = it . next ( ) ) {
// fprintf(stderr, "remove site %p from %p\n", s, v);
it . remove ( c ) ;
2008-04-30 15:44:17 +00:00
break ;
}
}
}
2008-04-19 07:03:59 +00:00
void
clearSites ( Context * c , Value * v )
{
2008-10-25 02:12:02 +00:00
// fprintf(stderr, "clear sites for %p\n", v);
2008-11-01 22:16:18 +00:00
for ( SiteIterator it ( v ) ; it . hasMore ( ) ; ) {
it . next ( ) ;
it . remove ( c ) ;
2008-04-19 07:03:59 +00:00
}
}
2008-07-05 20:21:13 +00:00
bool
valid ( Read * r )
{
return r and r - > valid ( ) ;
}
2008-11-01 22:16:18 +00:00
Read *
2008-07-05 20:21:13 +00:00
live ( Value * v )
{
2008-11-01 22:16:18 +00:00
if ( valid ( v - > reads ) ) return v - > reads ;
2008-11-01 19:14:13 +00:00
for ( Value * p = v - > buddy ; p ! = v ; p = p - > buddy ) {
2008-11-01 22:16:18 +00:00
if ( valid ( p - > reads ) ) return p - > reads ;
2008-11-01 19:14:13 +00:00
}
2008-11-01 22:16:18 +00:00
return 0 ;
2008-11-01 19:14:13 +00:00
}
2008-11-01 22:16:18 +00:00
Read *
2008-11-01 19:14:13 +00:00
liveNext ( Context * c , Value * v )
{
2008-11-01 22:16:18 +00:00
Read * r = v - > reads - > next ( c ) ;
if ( valid ( r ) ) return r ;
2008-11-01 19:14:13 +00:00
for ( Value * p = v - > buddy ; p ! = v ; p = p - > buddy ) {
2008-11-01 22:16:18 +00:00
if ( valid ( p - > reads ) ) return p - > reads ;
2008-11-01 19:14:13 +00:00
}
2008-11-01 22:16:18 +00:00
return 0 ;
2008-07-05 20:21:13 +00:00
}
2008-04-19 00:19:45 +00:00
void
2008-09-25 00:48:32 +00:00
nextRead ( Context * c , Event * e , Value * v )
2008-04-19 00:19:45 +00:00
{
2008-09-25 00:48:32 +00:00
assert ( c , e = = v - > reads - > event ) ;
2008-10-15 00:45:31 +00:00
// fprintf(stderr, "pop read %p from %p next %p event %p (%s)\n",
// v->reads, v, v->reads->next(c), e, (e ? e->name() : 0));
2008-04-19 07:03:59 +00:00
2008-09-15 02:28:42 +00:00
v - > reads = v - > reads - > next ( c ) ;
2008-07-05 20:21:13 +00:00
if ( not live ( v ) ) {
2008-04-19 07:03:59 +00:00
clearSites ( c , v ) ;
2008-04-19 00:19:45 +00:00
}
}
2008-10-12 00:23:08 +00:00
ConstantSite *
constantSite ( Context * c , Promise * value ) ;
2008-04-16 20:58:21 +00:00
class ConstantSite : public Site {
public :
ConstantSite ( Promise * value ) : value ( value ) { }
2008-10-04 17:26:35 +00:00
virtual void toString ( Context * , char * buffer , unsigned bufferSize ) {
if ( value . value - > resolved ( ) ) {
2008-10-05 00:14:43 +00:00
snprintf ( buffer , bufferSize , " constant % " LLD , value . value - > value ( ) ) ;
2008-10-04 17:26:35 +00:00
} else {
snprintf ( buffer , bufferSize , " constant unresolved " ) ;
}
}
2008-04-18 18:36:57 +00:00
virtual unsigned copyCost ( Context * , Site * s ) {
return ( s = = this ? 0 : 1 ) ;
2008-04-16 20:58:21 +00:00
}
2008-08-23 18:04:36 +00:00
virtual bool match ( Context * , uint8_t typeMask , uint64_t , int ) {
return typeMask & ( 1 < < ConstantOperand ) ;
}
2008-04-16 20:58:21 +00:00
virtual OperandType type ( Context * ) {
2008-04-17 22:07:32 +00:00
return ConstantOperand ;
2008-04-16 20:58:21 +00:00
}
virtual Assembler : : Operand * asAssemblerOperand ( Context * ) {
return & value ;
}
2008-10-12 00:23:08 +00:00
virtual Site * copy ( Context * c ) {
return constantSite ( c , value . value ) ;
}
2008-04-16 20:58:21 +00:00
Assembler : : Constant value ;
} ;
ConstantSite *
constantSite ( Context * c , Promise * value )
{
return new ( c - > zone - > allocate ( sizeof ( ConstantSite ) ) ) ConstantSite ( value ) ;
}
ResolvedPromise *
resolved ( Context * c , int64_t value )
{
return new ( c - > zone - > allocate ( sizeof ( ResolvedPromise ) ) )
ResolvedPromise ( value ) ;
}
ConstantSite *
constantSite ( Context * c , int64_t value )
{
return constantSite ( c , resolved ( c , value ) ) ;
}
2008-10-12 00:23:08 +00:00
AddressSite *
addressSite ( Context * c , Promise * address ) ;
2008-04-16 20:58:21 +00:00
class AddressSite : public Site {
public :
AddressSite ( Promise * address ) : address ( address ) { }
2008-10-04 17:26:35 +00:00
virtual void toString ( Context * , char * buffer , unsigned bufferSize ) {
if ( address . address - > resolved ( ) ) {
2008-10-05 00:14:43 +00:00
snprintf ( buffer , bufferSize , " address % " LLD , address . address - > value ( ) ) ;
2008-10-04 17:26:35 +00:00
} else {
snprintf ( buffer , bufferSize , " address unresolved " ) ;
}
}
2008-04-18 18:36:57 +00:00
virtual unsigned copyCost ( Context * , Site * s ) {
return ( s = = this ? 0 : 3 ) ;
2008-04-16 20:58:21 +00:00
}
2008-08-23 18:04:36 +00:00
virtual bool match ( Context * , uint8_t typeMask , uint64_t , int ) {
return typeMask & ( 1 < < AddressOperand ) ;
}
2008-04-16 20:58:21 +00:00
virtual OperandType type ( Context * ) {
2008-04-17 22:07:32 +00:00
return AddressOperand ;
2008-04-16 20:58:21 +00:00
}
virtual Assembler : : Operand * asAssemblerOperand ( Context * ) {
return & address ;
}
2008-10-12 00:23:08 +00:00
virtual Site * copy ( Context * c ) {
return addressSite ( c , address . address ) ;
}
2008-04-16 20:58:21 +00:00
Assembler : : Address address ;
} ;
AddressSite *
addressSite ( Context * c , Promise * address )
{
return new ( c - > zone - > allocate ( sizeof ( AddressSite ) ) ) AddressSite ( address ) ;
}
2008-05-15 00:04:25 +00:00
void
2008-09-27 22:01:39 +00:00
freeze ( Context * c , Register * r )
2008-05-15 00:04:25 +00:00
{
2008-09-27 22:01:39 +00:00
assert ( c , c - > availableRegisterCount ) ;
2008-05-15 00:04:25 +00:00
if ( DebugRegisters ) {
fprintf ( stderr , " freeze %d to %d \n " , r - > number , r - > freezeCount + 1 ) ;
}
+ + r - > freezeCount ;
2008-09-27 22:01:39 +00:00
- - c - > availableRegisterCount ;
2008-05-15 00:04:25 +00:00
}
void
2008-09-27 22:01:39 +00:00
thaw ( Context * c , Register * r )
2008-05-15 00:04:25 +00:00
{
2008-09-27 22:01:39 +00:00
assert ( c , r - > freezeCount ) ;
2008-05-15 00:04:25 +00:00
if ( DebugRegisters ) {
fprintf ( stderr , " thaw %d to %d \n " , r - > number , r - > freezeCount - 1 ) ;
}
- - r - > freezeCount ;
2008-09-27 22:01:39 +00:00
+ + c - > availableRegisterCount ;
2008-05-15 00:04:25 +00:00
}
2008-05-12 13:54:47 +00:00
Register *
2008-09-24 00:01:42 +00:00
acquire ( Context * c , uint32_t mask , Stack * stack , Local * locals ,
2008-07-17 23:34:38 +00:00
unsigned newSize , Value * newValue , RegisterSite * newSite ) ;
2008-04-16 20:58:21 +00:00
2008-04-19 00:19:45 +00:00
void
2008-05-12 13:54:47 +00:00
release ( Context * c , Register * r ) ;
2008-04-19 00:19:45 +00:00
2008-05-15 20:00:57 +00:00
Register *
2008-09-24 00:01:42 +00:00
validate ( Context * c , uint32_t mask , Stack * stack , Local * locals ,
2008-08-23 18:04:36 +00:00
unsigned size , Value * value , RegisterSite * site , Register * current ) ;
2008-05-15 20:00:57 +00:00
2008-10-12 00:23:08 +00:00
RegisterSite *
freeRegisterSite ( Context * c , uint64_t mask = ~ static_cast < uint64_t > ( 0 ) ) ;
2008-04-16 20:58:21 +00:00
class RegisterSite : public Site {
public :
2008-05-13 17:27:57 +00:00
RegisterSite ( uint64_t mask , Register * low = 0 , Register * high = 0 ) :
mask ( mask ) , low ( low ) , high ( high ) , register_ ( NoRegister , NoRegister )
2008-05-12 13:54:47 +00:00
{ }
2008-05-14 23:19:41 +00:00
void sync ( Context * c UNUSED ) {
2008-05-12 13:54:47 +00:00
assert ( c , low ) ;
register_ . low = low - > number ;
register_ . high = ( high ? high - > number : NoRegister ) ;
}
2008-04-16 20:58:21 +00:00
2008-10-04 17:26:35 +00:00
virtual void toString ( Context * c , char * buffer , unsigned bufferSize ) {
if ( low ) {
sync ( c ) ;
snprintf ( buffer , bufferSize , " register %d %d " ,
register_ . low , register_ . high ) ;
} else {
snprintf ( buffer , bufferSize , " register unacquired " ) ;
}
}
2008-04-16 20:58:21 +00:00
virtual unsigned copyCost ( Context * c , Site * s ) {
2008-05-12 13:54:47 +00:00
sync ( c ) ;
2008-04-16 20:58:21 +00:00
if ( s and
( this = = s or
2008-04-17 22:07:32 +00:00
( s - > type ( c ) = = RegisterOperand
2008-05-12 13:54:47 +00:00
and ( static_cast < RegisterSite * > ( s ) - > mask
& ( static_cast < uint64_t > ( 1 ) < < register_ . low ) )
and ( register_ . high = = NoRegister
or ( static_cast < RegisterSite * > ( s ) - > mask
& ( static_cast < uint64_t > ( 1 ) < < ( register_ . high + 32 ) ) ) ) ) ) )
2008-04-16 20:58:21 +00:00
{
return 0 ;
} else {
return 2 ;
}
}
2008-08-23 18:04:36 +00:00
virtual bool match ( Context * c , uint8_t typeMask , uint64_t registerMask , int )
{
if ( ( typeMask & ( 1 < < RegisterOperand ) ) and low ) {
sync ( c ) ;
return ( ( static_cast < uint64_t > ( 1 ) < < register_ . low ) & registerMask )
and ( register_ . high = = NoRegister
or ( ( static_cast < uint64_t > ( 1 ) < < ( register_ . high + 32 ) )
& registerMask ) ) ;
} else {
return false ;
}
}
2008-09-24 00:01:42 +00:00
virtual void acquire ( Context * c , Stack * stack , Local * locals , unsigned size ,
2008-07-17 23:34:38 +00:00
Value * v )
{
low = : : validate ( c , mask , stack , locals , size , v , this , low ) ;
2008-05-20 22:47:53 +00:00
if ( size > BytesPerWord ) {
2008-09-27 22:01:39 +00:00
: : freeze ( c , low ) ;
2008-07-17 23:34:38 +00:00
high = : : validate ( c , mask > > 32 , stack , locals , size , v , this , high ) ;
2008-09-27 22:01:39 +00:00
: : thaw ( c , low ) ;
2008-05-20 22:47:53 +00:00
}
2008-04-19 00:19:45 +00:00
}
virtual void release ( Context * c ) {
2008-05-12 13:54:47 +00:00
assert ( c , low ) ;
: : release ( c , low ) ;
if ( high ) {
: : release ( c , high ) ;
}
}
2008-05-14 23:19:41 +00:00
virtual void freeze ( Context * c UNUSED ) {
2008-05-12 13:54:47 +00:00
assert ( c , low ) ;
2008-09-27 22:01:39 +00:00
: : freeze ( c , low ) ;
2008-05-12 13:54:47 +00:00
if ( high ) {
2008-09-27 22:01:39 +00:00
: : freeze ( c , high ) ;
2008-05-12 13:54:47 +00:00
}
}
2008-05-14 23:19:41 +00:00
virtual void thaw ( Context * c UNUSED ) {
2008-05-12 13:54:47 +00:00
assert ( c , low ) ;
2008-09-27 22:01:39 +00:00
: : thaw ( c , low ) ;
2008-05-12 13:54:47 +00:00
if ( high ) {
2008-09-27 22:01:39 +00:00
: : thaw ( c , high ) ;
2008-05-12 13:54:47 +00:00
}
2008-04-16 20:58:21 +00:00
}
2008-10-15 00:45:31 +00:00
virtual bool usesRegister ( Context * c , int r ) {
sync ( c ) ;
return register_ . low = = r or register_ . high = = r ;
}
2008-04-16 20:58:21 +00:00
virtual OperandType type ( Context * ) {
2008-04-17 22:07:32 +00:00
return RegisterOperand ;
2008-04-16 20:58:21 +00:00
}
2008-05-12 13:54:47 +00:00
virtual Assembler : : Operand * asAssemblerOperand ( Context * c ) {
sync ( c ) ;
2008-04-16 20:58:21 +00:00
return & register_ ;
}
2008-10-12 00:23:08 +00:00
virtual Site * copy ( Context * c ) {
uint64_t mask ;
if ( low ) {
sync ( c ) ;
mask = static_cast < uint64_t > ( 1 ) < < register_ . low ;
if ( register_ . high ! = NoRegister ) {
mask | = static_cast < uint64_t > ( 1 ) < < register_ . high ;
}
} else {
mask = this - > mask ;
2008-10-04 17:26:35 +00:00
}
2008-10-12 00:23:08 +00:00
return freeRegisterSite ( c , mask ) ;
2008-10-04 17:26:35 +00:00
}
2008-05-12 13:54:47 +00:00
uint64_t mask ;
Register * low ;
Register * high ;
2008-04-16 20:58:21 +00:00
Assembler : : Register register_ ;
} ;
RegisterSite *
registerSite ( Context * c , int low , int high = NoRegister )
{
2008-04-19 00:19:45 +00:00
assert ( c , low ! = NoRegister ) ;
2008-08-23 18:04:36 +00:00
assert ( c , low < static_cast < int > ( c - > arch - > registerCount ( ) ) ) ;
2008-04-19 00:19:45 +00:00
assert ( c , high = = NoRegister
2008-08-23 18:04:36 +00:00
or high < static_cast < int > ( c - > arch - > registerCount ( ) ) ) ;
2008-04-19 00:19:45 +00:00
2008-05-13 17:27:57 +00:00
Register * hr ;
2008-05-12 13:54:47 +00:00
if ( high = = NoRegister ) {
2008-05-13 17:27:57 +00:00
hr = 0 ;
2008-05-12 13:54:47 +00:00
} else {
2008-05-13 17:27:57 +00:00
hr = c - > registers [ high ] ;
2008-05-12 13:54:47 +00:00
}
2008-04-16 20:58:21 +00:00
return new ( c - > zone - > allocate ( sizeof ( RegisterSite ) ) )
2008-05-15 23:19:23 +00:00
RegisterSite ( ~ static_cast < uint64_t > ( 0 ) , c - > registers [ low ] , hr ) ;
2008-04-16 20:58:21 +00:00
}
2008-04-17 22:07:32 +00:00
RegisterSite *
2008-10-12 00:23:08 +00:00
freeRegisterSite ( Context * c , uint64_t mask )
2008-05-12 13:54:47 +00:00
{
return new ( c - > zone - > allocate ( sizeof ( RegisterSite ) ) )
RegisterSite ( mask ) ;
}
2008-04-17 22:07:32 +00:00
2008-05-12 13:54:47 +00:00
Register *
increment ( Context * c , int i )
2008-04-20 00:43:12 +00:00
{
2008-05-12 13:54:47 +00:00
Register * r = c - > registers [ i ] ;
2008-04-20 00:43:12 +00:00
if ( DebugRegisters ) {
2008-05-12 13:54:47 +00:00
fprintf ( stderr , " increment %d to %d \n " , r - > number , r - > refCount + 1 ) ;
2008-04-20 00:43:12 +00:00
}
2008-05-12 13:54:47 +00:00
+ + r - > refCount ;
return r ;
2008-04-20 00:43:12 +00:00
}
void
2008-05-14 23:19:41 +00:00
decrement ( Context * c UNUSED , Register * r )
2008-04-20 00:43:12 +00:00
{
2008-05-12 13:54:47 +00:00
assert ( c , r - > refCount > 0 ) ;
2008-04-20 00:43:12 +00:00
if ( DebugRegisters ) {
2008-05-15 00:04:25 +00:00
fprintf ( stderr , " decrement %d to %d \n " , r - > number , r - > refCount - 1 ) ;
2008-04-20 00:43:12 +00:00
}
2008-05-12 13:54:47 +00:00
- - r - > refCount ;
2008-04-20 00:43:12 +00:00
}
2008-09-28 21:56:12 +00:00
void
acquireFrameIndex ( Context * c , int index , Stack * stack , Local * locals ,
unsigned newSize , Value * newValue , MemorySite * newSite ,
bool recurse = true ) ;
void
releaseFrameIndex ( Context * c , int index , bool recurse = true ) ;
2008-10-12 00:23:08 +00:00
MemorySite *
memorySite ( Context * c , int base , int offset = 0 , int index = NoRegister ,
unsigned scale = 1 ) ;
2008-04-16 20:58:21 +00:00
class MemorySite : public Site {
public :
2008-04-17 02:55:38 +00:00
MemorySite ( int base , int offset , int index , unsigned scale ) :
2008-08-23 18:04:36 +00:00
base ( 0 ) , index ( 0 ) , value ( base , offset , index , scale )
2008-04-16 20:58:21 +00:00
{ }
2008-05-14 23:19:41 +00:00
void sync ( Context * c UNUSED ) {
2008-05-12 13:54:47 +00:00
assert ( c , base ) ;
value . base = base - > number ;
value . index = ( index ? index - > number : NoRegister ) ;
}
2008-10-04 17:26:35 +00:00
virtual void toString ( Context * c , char * buffer , unsigned bufferSize ) {
if ( base ) {
sync ( c ) ;
snprintf ( buffer , bufferSize , " memory %d %d %d %d " ,
value . base , value . offset , value . index , value . scale ) ;
} else {
snprintf ( buffer , bufferSize , " memory unacquired " ) ;
}
}
2008-04-16 20:58:21 +00:00
virtual unsigned copyCost ( Context * c , Site * s ) {
2008-05-12 13:54:47 +00:00
sync ( c ) ;
2008-04-16 20:58:21 +00:00
if ( s and
( this = = s or
2008-04-17 22:07:32 +00:00
( s - > type ( c ) = = MemoryOperand
and static_cast < MemorySite * > ( s ) - > value . base = = value . base
and static_cast < MemorySite * > ( s ) - > value . offset = = value . offset
and static_cast < MemorySite * > ( s ) - > value . index = = value . index
and static_cast < MemorySite * > ( s ) - > value . scale = = value . scale ) ) )
2008-04-16 20:58:21 +00:00
{
return 0 ;
} else {
return 4 ;
}
}
2008-08-23 18:04:36 +00:00
virtual bool match ( Context * c , uint8_t typeMask , uint64_t , int frameIndex ) {
if ( typeMask & ( 1 < < MemoryOperand ) ) {
sync ( c ) ;
if ( value . base = = c - > arch - > stack ( ) ) {
assert ( c , value . index = = NoRegister ) ;
return frameIndex = = AnyFrameIndex
| | ( frameIndex ! = NoFrameIndex
2008-10-25 02:12:02 +00:00
& & static_cast < int > ( frameIndexToOffset ( c , frameIndex ) )
= = value . offset ) ;
2008-08-23 18:04:36 +00:00
} else {
2008-10-19 00:15:57 +00:00
return true ;
2008-08-23 18:04:36 +00:00
}
} else {
return false ;
}
}
2008-09-28 21:56:12 +00:00
virtual void acquire ( Context * c , Stack * stack , Local * locals , unsigned size ,
Value * v )
{
2008-05-12 13:54:47 +00:00
base = increment ( c , value . base ) ;
2008-04-19 00:19:45 +00:00
if ( value . index ! = NoRegister ) {
2008-05-12 13:54:47 +00:00
index = increment ( c , value . index ) ;
2008-04-19 00:19:45 +00:00
}
2008-09-28 21:56:12 +00:00
if ( value . base = = c - > arch - > stack ( ) ) {
assert ( c , value . index = = NoRegister ) ;
acquireFrameIndex
2008-10-25 02:12:02 +00:00
( c , offsetToFrameIndex ( c , value . offset ) , stack , locals , size , v ,
2008-09-28 21:56:12 +00:00
this ) ;
}
2008-04-19 00:19:45 +00:00
}
virtual void release ( Context * c ) {
2008-09-28 21:56:12 +00:00
if ( value . base = = c - > arch - > stack ( ) ) {
assert ( c , value . index = = NoRegister ) ;
2008-10-25 02:12:02 +00:00
releaseFrameIndex ( c , offsetToFrameIndex ( c , value . offset ) ) ;
2008-09-28 21:56:12 +00:00
}
2008-05-12 13:54:47 +00:00
decrement ( c , base ) ;
if ( index ) {
decrement ( c , index ) ;
2008-04-19 00:19:45 +00:00
}
}
2008-10-15 00:45:31 +00:00
virtual bool usesRegister ( Context * c , int r ) {
sync ( c ) ;
return value . base = = r or value . index = = r ;
}
2008-04-16 20:58:21 +00:00
virtual OperandType type ( Context * ) {
2008-04-17 22:07:32 +00:00
return MemoryOperand ;
2008-04-16 20:58:21 +00:00
}
2008-05-12 13:54:47 +00:00
virtual Assembler : : Operand * asAssemblerOperand ( Context * c ) {
sync ( c ) ;
2008-04-16 20:58:21 +00:00
return & value ;
}
2008-10-12 00:23:08 +00:00
virtual Site * copy ( Context * c ) {
return memorySite ( c , value . base , value . offset , value . index , value . scale ) ;
}
2008-05-12 13:54:47 +00:00
Register * base ;
Register * index ;
2008-04-16 20:58:21 +00:00
Assembler : : Memory value ;
} ;
MemorySite *
2008-10-12 00:23:08 +00:00
memorySite ( Context * c , int base , int offset , int index , unsigned scale )
2008-04-16 20:58:21 +00:00
{
return new ( c - > zone - > allocate ( sizeof ( MemorySite ) ) )
MemorySite ( base , offset , index , scale ) ;
}
2008-08-23 18:04:36 +00:00
MemorySite *
frameSite ( Context * c , int frameIndex )
{
assert ( c , frameIndex > = 0 ) ;
2008-10-19 00:15:57 +00:00
return memorySite
2008-10-25 02:12:02 +00:00
( c , c - > arch - > stack ( ) , frameIndexToOffset ( c , frameIndex ) ) ;
2008-08-23 18:04:36 +00:00
}
2008-07-05 20:21:13 +00:00
Site *
targetOrNull ( Context * c , Value * v , Read * r )
2008-05-04 20:55:34 +00:00
{
2008-07-05 20:21:13 +00:00
if ( v - > target ) {
return v - > target ;
2008-05-22 17:15:18 +00:00
} else {
2008-07-05 20:21:13 +00:00
return r - > allocateSite ( c ) ;
2008-05-22 17:15:18 +00:00
}
2008-05-04 20:55:34 +00:00
}
2008-07-05 20:21:13 +00:00
Site *
targetOrNull ( Context * c , Value * v )
2008-05-04 20:55:34 +00:00
{
2008-07-05 20:21:13 +00:00
if ( v - > target ) {
return v - > target ;
} else if ( live ( v ) ) {
2008-11-01 19:14:13 +00:00
return v - > reads - > allocateSite ( c ) ;
2008-07-05 20:21:13 +00:00
}
return 0 ;
2008-05-04 20:55:34 +00:00
}
2008-05-06 21:13:02 +00:00
Site *
2008-07-05 20:21:13 +00:00
pickSite ( Context * c , Value * value , uint8_t typeMask , uint64_t registerMask ,
int frameIndex )
2008-05-06 21:13:02 +00:00
{
2008-07-05 20:21:13 +00:00
Site * site = 0 ;
unsigned copyCost = 0xFFFFFFFF ;
2008-11-01 19:14:13 +00:00
for ( SiteIterator it ( value ) ; it . hasMore ( ) ; ) {
Site * s = it . next ( ) ;
2008-07-05 20:21:13 +00:00
if ( s - > match ( c , typeMask , registerMask , frameIndex ) ) {
unsigned v = s - > copyCost ( c , 0 ) ;
if ( v < copyCost ) {
site = s ;
copyCost = v ;
}
}
2008-05-06 21:13:02 +00:00
}
2008-07-05 20:21:13 +00:00
return site ;
2008-05-06 21:13:02 +00:00
}
Site *
2008-07-05 20:21:13 +00:00
allocateSite ( Context * c , uint8_t typeMask , uint64_t registerMask ,
int frameIndex )
2008-05-06 21:13:02 +00:00
{
2008-07-05 20:21:13 +00:00
if ( ( typeMask & ( 1 < < RegisterOperand ) ) and registerMask ) {
return freeRegisterSite ( c , registerMask ) ;
} else if ( frameIndex > = 0 ) {
return frameSite ( c , frameIndex ) ;
} else {
2008-09-24 00:01:42 +00:00
return 0 ;
2008-05-06 21:13:02 +00:00
}
}
2008-08-28 22:43:35 +00:00
class SingleRead : public Read {
public :
SingleRead ( unsigned size , uint8_t typeMask , uint64_t registerMask ,
int frameIndex ) :
2008-09-24 00:01:42 +00:00
Read ( size ) , next_ ( 0 ) , typeMask ( typeMask ) , registerMask ( registerMask ) ,
2008-08-28 22:43:35 +00:00
frameIndex ( frameIndex )
{ }
virtual Site * pickSite ( Context * c , Value * value ) {
return : : pickSite ( c , value , typeMask , registerMask , frameIndex ) ;
}
virtual Site * allocateSite ( Context * c ) {
return : : allocateSite ( c , typeMask , registerMask , frameIndex ) ;
}
2008-09-15 02:28:42 +00:00
virtual bool intersect ( uint8_t * typeMask , uint64_t * registerMask ,
2008-08-28 22:43:35 +00:00
int * frameIndex )
{
* typeMask & = this - > typeMask ;
* registerMask & = this - > registerMask ;
* frameIndex = intersectFrameIndexes ( * frameIndex , this - > frameIndex ) ;
2008-09-15 02:28:42 +00:00
return true ;
2008-08-28 22:43:35 +00:00
}
virtual bool valid ( ) {
return true ;
}
2008-09-13 21:09:26 +00:00
virtual void append ( Context * c , Read * r ) {
assert ( c , next_ = = 0 ) ;
next_ = r ;
}
2008-09-15 02:28:42 +00:00
virtual Read * next ( Context * ) {
2008-09-13 21:09:26 +00:00
return next_ ;
}
Read * next_ ;
2008-08-28 22:43:35 +00:00
uint8_t typeMask ;
uint64_t registerMask ;
int frameIndex ;
} ;
Read *
read ( Context * c , unsigned size , uint8_t typeMask , uint64_t registerMask ,
int frameIndex )
{
2008-09-28 21:56:12 +00:00
assert ( c , ( typeMask ! = 1 < < MemoryOperand ) or frameIndex > = 0 ) ;
2008-08-28 22:43:35 +00:00
return new ( c - > zone - > allocate ( sizeof ( SingleRead ) ) )
SingleRead ( size , typeMask , registerMask , frameIndex ) ;
}
Read *
anyRegisterRead ( Context * c , unsigned size )
{
return read ( c , size , 1 < < RegisterOperand , ~ static_cast < uint64_t > ( 0 ) ,
NoFrameIndex ) ;
}
Read *
registerOrConstantRead ( Context * c , unsigned size )
{
return read ( c , size , ( 1 < < RegisterOperand ) | ( 1 < < ConstantOperand ) ,
~ static_cast < uint64_t > ( 0 ) , NoFrameIndex ) ;
}
Read *
fixedRegisterRead ( Context * c , unsigned size , int low , int high = NoRegister )
{
uint64_t mask ;
if ( high = = NoRegister ) {
mask = ( ~ static_cast < uint64_t > ( 0 ) < < 32 )
| ( static_cast < uint64_t > ( 1 ) < < low ) ;
} else {
mask = ( static_cast < uint64_t > ( 1 ) < < ( high + 32 ) )
| ( static_cast < uint64_t > ( 1 ) < < low ) ;
}
return read ( c , size , 1 < < RegisterOperand , mask , NoFrameIndex ) ;
}
2008-07-05 20:21:13 +00:00
class MultiRead : public Read {
2008-05-06 21:13:02 +00:00
public :
2008-09-24 00:01:42 +00:00
MultiRead ( unsigned size ) :
Read ( size ) , reads ( 0 ) , lastRead ( 0 ) , firstTarget ( 0 ) , lastTarget ( 0 ) ,
visited ( false )
2008-05-04 20:55:34 +00:00
{ }
2008-08-23 18:04:36 +00:00
virtual Site * pickSite ( Context * c , Value * value ) {
2008-07-05 20:21:13 +00:00
uint8_t typeMask = ~ static_cast < uint8_t > ( 0 ) ;
uint64_t registerMask = ~ static_cast < uint64_t > ( 0 ) ;
int frameIndex = AnyFrameIndex ;
intersect ( & typeMask , & registerMask , & frameIndex ) ;
2008-05-04 20:55:34 +00:00
2008-07-05 20:21:13 +00:00
return : : pickSite ( c , value , typeMask , registerMask , frameIndex ) ;
}
virtual Site * allocateSite ( Context * c ) {
uint8_t typeMask = ~ static_cast < uint8_t > ( 0 ) ;
uint64_t registerMask = ~ static_cast < uint64_t > ( 0 ) ;
int frameIndex = AnyFrameIndex ;
intersect ( & typeMask , & registerMask , & frameIndex ) ;
return : : allocateSite ( c , typeMask , registerMask , frameIndex ) ;
}
2008-09-15 02:28:42 +00:00
virtual bool intersect ( uint8_t * typeMask , uint64_t * registerMask ,
2008-07-05 20:21:13 +00:00
int * frameIndex )
{
2008-09-15 02:28:42 +00:00
bool result = false ;
2008-09-13 21:09:26 +00:00
if ( not visited ) {
visited = true ;
2008-09-15 02:28:42 +00:00
for ( Cell * * cell = & reads ; * cell ; ) {
Read * r = static_cast < Read * > ( ( * cell ) - > value ) ;
bool valid = r - > intersect ( typeMask , registerMask , frameIndex ) ;
if ( valid ) {
result = true ;
cell = & ( ( * cell ) - > next ) ;
} else {
* cell = ( * cell ) - > next ;
}
2008-09-13 21:09:26 +00:00
}
visited = false ;
2008-05-04 20:55:34 +00:00
}
2008-09-15 02:28:42 +00:00
return result ;
2008-07-05 20:21:13 +00:00
}
2008-05-04 20:55:34 +00:00
2008-07-05 20:21:13 +00:00
virtual bool valid ( ) {
2008-09-15 02:28:42 +00:00
bool result = false ;
2008-09-13 21:09:26 +00:00
if ( not visited ) {
visited = true ;
2008-09-15 02:28:42 +00:00
for ( Cell * * cell = & reads ; * cell ; ) {
Read * r = static_cast < Read * > ( ( * cell ) - > value ) ;
2008-09-13 21:09:26 +00:00
if ( r - > valid ( ) ) {
2008-09-15 02:28:42 +00:00
result = true ;
cell = & ( ( * cell ) - > next ) ;
} else {
* cell = ( * cell ) - > next ;
2008-09-13 21:09:26 +00:00
}
2008-07-05 20:21:13 +00:00
}
2008-09-13 21:09:26 +00:00
visited = false ;
2008-05-04 20:55:34 +00:00
}
2008-09-15 02:28:42 +00:00
return result ;
2008-05-04 20:55:34 +00:00
}
2008-09-13 21:09:26 +00:00
virtual void append ( Context * c , Read * r ) {
Cell * cell = cons ( c , r , 0 ) ;
if ( lastRead = = 0 ) {
reads = cell ;
} else {
lastRead - > next = cell ;
}
lastRead = cell ;
2008-09-15 02:28:42 +00:00
lastTarget - > value = r ;
2008-09-13 21:09:26 +00:00
}
2008-09-15 02:28:42 +00:00
virtual Read * next ( Context * c ) {
abort ( c ) ;
2008-09-13 21:09:26 +00:00
}
2008-09-15 02:28:42 +00:00
void allocateTarget ( Context * c ) {
Cell * cell = cons ( c , 0 , 0 ) ;
2008-10-14 00:18:18 +00:00
if ( lastTarget ) {
2008-09-15 02:28:42 +00:00
lastTarget - > next = cell ;
2008-10-14 00:18:18 +00:00
} else {
firstTarget = cell ;
2008-09-15 02:28:42 +00:00
}
lastTarget = cell ;
}
Read * nextTarget ( ) {
Read * r = static_cast < Read * > ( firstTarget - > value ) ;
firstTarget = firstTarget - > next ;
return r ;
2008-09-13 21:09:26 +00:00
}
2008-07-05 20:21:13 +00:00
Cell * reads ;
2008-09-13 21:09:26 +00:00
Cell * lastRead ;
2008-09-15 02:28:42 +00:00
Cell * firstTarget ;
Cell * lastTarget ;
2008-09-13 21:09:26 +00:00
bool visited ;
2008-04-16 20:58:21 +00:00
} ;
2008-07-05 20:21:13 +00:00
MultiRead *
2008-09-24 00:01:42 +00:00
multiRead ( Context * c , unsigned size )
2008-05-04 20:55:34 +00:00
{
2008-09-24 00:01:42 +00:00
return new ( c - > zone - > allocate ( sizeof ( MultiRead ) ) ) MultiRead ( size ) ;
2008-05-04 20:55:34 +00:00
}
2008-09-22 00:58:54 +00:00
class StubRead : public Read {
public :
2008-09-24 00:01:42 +00:00
StubRead ( unsigned size ) :
2008-10-14 00:18:18 +00:00
Read ( size ) , next_ ( 0 ) , read ( 0 ) , visited ( false )
2008-09-22 00:58:54 +00:00
{ }
virtual Site * pickSite ( Context * c , Value * value ) {
uint8_t typeMask = ~ static_cast < uint8_t > ( 0 ) ;
uint64_t registerMask = ~ static_cast < uint64_t > ( 0 ) ;
int frameIndex = AnyFrameIndex ;
intersect ( & typeMask , & registerMask , & frameIndex ) ;
return : : pickSite ( c , value , typeMask , registerMask , frameIndex ) ;
}
virtual Site * allocateSite ( Context * c ) {
uint8_t typeMask = ~ static_cast < uint8_t > ( 0 ) ;
uint64_t registerMask = ~ static_cast < uint64_t > ( 0 ) ;
int frameIndex = AnyFrameIndex ;
intersect ( & typeMask , & registerMask , & frameIndex ) ;
return : : allocateSite ( c , typeMask , registerMask , frameIndex ) ;
}
virtual bool intersect ( uint8_t * typeMask , uint64_t * registerMask ,
int * frameIndex )
{
if ( not visited ) {
visited = true ;
if ( read ) {
bool valid = read - > intersect ( typeMask , registerMask , frameIndex ) ;
if ( not valid ) {
read = 0 ;
}
}
visited = false ;
}
return true ;
}
virtual bool valid ( ) {
return true ;
}
2008-10-14 00:18:18 +00:00
virtual void append ( Context * c , Read * r ) {
assert ( c , next_ = = 0 ) ;
next_ = r ;
2008-09-22 00:58:54 +00:00
}
2008-10-14 00:18:18 +00:00
virtual Read * next ( Context * ) {
return next_ ;
2008-09-22 00:58:54 +00:00
}
2008-10-14 00:18:18 +00:00
Read * next_ ;
2008-09-22 00:58:54 +00:00
Read * read ;
bool visited ;
} ;
StubRead *
2008-09-24 00:01:42 +00:00
stubRead ( Context * c , unsigned size )
2008-09-22 00:58:54 +00:00
{
2008-09-24 00:01:42 +00:00
return new ( c - > zone - > allocate ( sizeof ( StubRead ) ) ) StubRead ( size ) ;
2008-09-22 00:58:54 +00:00
}
2008-04-18 17:00:55 +00:00
Site *
2008-05-12 13:54:47 +00:00
targetOrRegister ( Context * c , Value * v )
2008-04-18 17:00:55 +00:00
{
2008-05-12 13:54:47 +00:00
Site * s = targetOrNull ( c , v ) ;
if ( s ) {
2008-04-18 17:00:55 +00:00
return s ;
} else {
2008-05-15 23:19:23 +00:00
return freeRegisterSite ( c ) ;
2008-04-18 17:00:55 +00:00
}
}
2008-04-17 22:07:32 +00:00
Site *
2008-11-01 19:14:13 +00:00
targetOrRegister ( Context * c , Value * v , Read * r )
{
Site * s = targetOrNull ( c , v , r ) ;
if ( s ) {
return s ;
} else {
return freeRegisterSite ( c ) ;
}
}
Site *
pick ( Context * c , Value * value , Site * target = 0 , unsigned * cost = 0 )
2008-04-17 22:07:32 +00:00
{
Site * site = 0 ;
unsigned copyCost = 0xFFFFFFFF ;
2008-11-01 19:14:13 +00:00
for ( SiteIterator it ( value ) ; it . hasMore ( ) ; ) {
Site * s = it . next ( ) ;
2008-04-17 22:07:32 +00:00
unsigned v = s - > copyCost ( c , target ) ;
if ( v < copyCost ) {
site = s ;
copyCost = v ;
}
}
if ( cost ) * cost = copyCost ;
return site ;
}
2008-10-12 00:23:08 +00:00
void
move ( Context * c , Stack * stack , Local * locals , unsigned size , Value * value ,
Site * src , Site * dst )
{
if ( dst - > type ( c ) = = MemoryOperand
and ( src - > type ( c ) = = MemoryOperand
or src - > type ( c ) = = AddressOperand ) )
{
Site * tmp = freeRegisterSite ( c ) ;
addSite ( c , stack , locals , size , value , tmp ) ;
2008-10-19 00:15:57 +00:00
char srcb [ 256 ] ; src - > toString ( c , srcb , 256 ) ;
char tmpb [ 256 ] ; tmp - > toString ( c , tmpb , 256 ) ;
fprintf ( stderr , " move %s to %s for %p \n " , srcb , tmpb , value ) ;
2008-10-12 00:23:08 +00:00
apply ( c , Move , size , src , size , tmp ) ;
src = tmp ;
}
addSite ( c , stack , locals , size , value , dst ) ;
2008-10-19 00:15:57 +00:00
char srcb [ 256 ] ; src - > toString ( c , srcb , 256 ) ;
char dstb [ 256 ] ; dst - > toString ( c , dstb , 256 ) ;
fprintf ( stderr , " move %s to %s for %p \n " , srcb , dstb , value ) ;
2008-10-12 00:23:08 +00:00
apply ( c , Move , size , src , size , dst ) ;
}
2008-10-15 00:45:31 +00:00
void
toString ( Context * c , Site * sites , char * buffer , unsigned size )
{
2008-11-01 19:14:13 +00:00
if ( sites ) {
sites - > toString ( c , buffer , size ) ;
if ( sites - > next ) {
unsigned length = strlen ( buffer ) ;
assert ( c , length + 2 < size ) ;
memcpy ( buffer + length , " , " , 2 ) ;
length + = 2 ;
sites - > next - > toString ( c , buffer + length , size - length ) ;
}
2008-11-01 22:16:18 +00:00
} else {
assert ( c , size ) ;
* buffer = 0 ;
2008-10-15 00:45:31 +00:00
}
}
void
2008-11-01 19:14:13 +00:00
releaseRegister ( Context * c , Value * v , unsigned frameIndex , unsigned sizeInBytes , int r )
2008-10-15 00:45:31 +00:00
{
2008-11-01 19:14:13 +00:00
Site * source = 0 ;
for ( Site * * s = & ( v - > sites ) ; * s ; ) {
if ( ( * s ) - > usesRegister ( c , r ) ) {
char buffer [ 256 ] ; ( * s ) - > toString ( c , buffer , 256 ) ;
fprintf ( stderr , " %p (%s) in %p at %d uses %d \n " , * s , buffer , v , frameIndex , r ) ;
2008-10-15 00:45:31 +00:00
2008-11-01 19:14:13 +00:00
source = * s ;
* s = ( * s ) - > next ;
source - > release ( c ) ;
} else {
char buffer [ 256 ] ; ( * s ) - > toString ( c , buffer , 256 ) ;
fprintf ( stderr , " %p (%s) in %p at %d does not use %d \n " , * s , buffer , v , frameIndex , r ) ;
s = & ( ( * s ) - > next ) ;
2008-10-15 00:45:31 +00:00
}
2008-11-01 19:14:13 +00:00
}
2008-10-15 00:45:31 +00:00
2008-11-01 22:16:18 +00:00
if ( not hasSite ( v ) ) {
2008-11-01 19:14:13 +00:00
move ( c , c - > stack , c - > locals , sizeInBytes , v , source , frameSite ( c , frameIndex ) ) ;
2008-10-15 00:45:31 +00:00
}
2008-11-01 19:14:13 +00:00
char buffer [ 256 ] ; toString ( c , v - > sites , buffer , 256 ) ;
fprintf ( stderr , " %p is left with %s \n " , v , buffer ) ;
2008-10-15 00:45:31 +00:00
}
void
releaseRegister ( Context * c , int r )
{
2008-11-01 19:14:13 +00:00
for ( FrameIterator it ( c , c - > stack , c - > locals ) ; it . hasMore ( ) ; ) {
FrameIterator : : Element e = it . next ( c ) ;
releaseRegister ( c , e . value , frameIndex ( c , & e ) , e . sizeInBytes , r ) ;
2008-10-15 00:45:31 +00:00
}
}
2008-04-27 20:15:18 +00:00
bool
2008-10-17 00:10:35 +00:00
trySteal ( Context * c , Site * site , Value * v , unsigned size , Stack * stack ,
Local * locals )
2008-04-27 20:15:18 +00:00
{
2008-11-01 22:16:18 +00:00
if ( not hasMoreThanOneSite ( v ) ) {
2008-07-17 23:34:38 +00:00
Site * saveSite = 0 ;
2008-10-25 02:12:02 +00:00
for ( unsigned li = 0 ; li < c - > localFootprint ; + + li ) {
2008-11-01 19:14:13 +00:00
Local * local = locals + li ;
if ( local - > value = = v ) {
2008-10-25 02:12:02 +00:00
saveSite = frameSite
2008-11-01 19:14:13 +00:00
( c , frameIndex ( c , li , ceiling ( local - > sizeInBytes , BytesPerWord ) ) ) ;
2008-07-17 23:34:38 +00:00
break ;
2008-04-27 20:15:18 +00:00
}
}
2008-07-17 23:34:38 +00:00
if ( saveSite = = 0 ) {
2008-08-23 18:04:36 +00:00
for ( Stack * s = stack ; s ; s = s - > next ) {
2008-07-17 23:34:38 +00:00
if ( s - > value = = v ) {
uint8_t typeMask ;
uint64_t registerMask ;
int frameIndex = AnyFrameIndex ;
v - > reads - > intersect ( & typeMask , & registerMask , & frameIndex ) ;
if ( frameIndex > = 0 ) {
saveSite = frameSite ( c , frameIndex ) ;
} else {
2008-10-25 02:12:02 +00:00
saveSite = frameSite
2008-11-01 19:14:13 +00:00
( c , : : frameIndex ( c , s - > index + c - > localFootprint , s - > sizeInWords ) ) ;
2008-07-17 23:34:38 +00:00
}
break ;
}
2008-05-18 01:26:36 +00:00
}
2008-07-17 23:34:38 +00:00
}
if ( saveSite ) {
2008-10-17 00:10:35 +00:00
move ( c , stack , locals , size , v , site , saveSite ) ;
2008-04-27 20:15:18 +00:00
} else {
2008-05-18 01:26:36 +00:00
if ( DebugRegisters ) {
2008-10-17 00:10:35 +00:00
fprintf ( stderr , " unable to steal %p from %p \n " , site , v ) ;
2008-05-18 01:26:36 +00:00
}
2008-04-27 20:15:18 +00:00
return false ;
}
}
2008-10-17 00:10:35 +00:00
removeSite ( c , v , site ) ;
2008-04-27 20:15:18 +00:00
return true ;
}
2008-10-17 00:10:35 +00:00
bool
trySteal ( Context * c , Register * r , Stack * stack , Local * locals )
{
assert ( c , r - > refCount = = 0 ) ;
Value * v = r - > value ;
2008-11-01 19:14:13 +00:00
assert ( c , live ( v ) ) ;
2008-10-17 00:10:35 +00:00
if ( DebugRegisters ) {
2008-11-01 22:16:18 +00:00
fprintf ( stderr , " try steal %d from %p \n " , r - > number , v ) ;
2008-10-17 00:10:35 +00:00
}
return trySteal ( c , r - > site , r - > value , r - > size , stack , locals ) ;
}
2008-04-21 00:21:48 +00:00
bool
2008-05-12 13:54:47 +00:00
used ( Context * c , Register * r )
{
Value * v = r - > value ;
return v and findSite ( c , v , r - > site ) ;
}
bool
usedExclusively ( Context * c , Register * r )
{
2008-11-01 22:16:18 +00:00
return used ( c , r ) and not hasMoreThanOneSite ( r - > value ) ;
2008-05-12 13:54:47 +00:00
}
unsigned
registerCost ( Context * c , Register * r )
{
if ( r - > reserved or r - > freezeCount ) {
return 6 ;
}
unsigned cost = 0 ;
if ( used ( c , r ) ) {
+ + cost ;
if ( usedExclusively ( c , r ) ) {
cost + = 2 ;
}
}
if ( r - > refCount ) {
cost + = 2 ;
}
return cost ;
}
Register *
pickRegister ( Context * c , uint32_t mask )
{
Register * register_ = 0 ;
unsigned cost = 5 ;
2008-08-23 18:04:36 +00:00
for ( int i = c - > arch - > registerCount ( ) - 1 ; i > = 0 ; - - i ) {
2008-05-12 13:54:47 +00:00
if ( ( 1 < < i ) & mask ) {
Register * r = c - > registers [ i ] ;
if ( ( static_cast < uint32_t > ( 1 ) < < i ) = = mask ) {
return r ;
}
unsigned myCost = registerCost ( c , r ) ;
if ( myCost < cost ) {
register_ = r ;
cost = myCost ;
}
}
}
expect ( c , register_ ) ;
return register_ ;
}
void
swap ( Context * c , Register * a , Register * b )
{
2008-05-15 23:19:23 +00:00
assert ( c , a ! = b ) ;
assert ( c , a - > number ! = b - > number ) ;
2008-05-12 13:54:47 +00:00
Assembler : : Register ar ( a - > number ) ;
Assembler : : Register br ( b - > number ) ;
c - > assembler - > apply
2008-08-16 17:45:36 +00:00
( Swap , BytesPerWord , RegisterOperand , & ar ,
BytesPerWord , RegisterOperand , & br ) ;
2008-05-12 13:54:47 +00:00
c - > registers [ a - > number ] = b ;
c - > registers [ b - > number ] = a ;
int t = a - > number ;
a - > number = b - > number ;
b - > number = t ;
}
Register *
2008-09-24 00:01:42 +00:00
replace ( Context * c , Stack * stack , Local * locals , Register * r )
2008-05-12 13:54:47 +00:00
{
2008-05-15 23:19:23 +00:00
uint32_t mask = ( r - > freezeCount ? r - > site - > mask : ~ 0 ) ;
2008-05-15 20:00:57 +00:00
2008-09-27 22:01:39 +00:00
freeze ( c , r ) ;
2008-07-17 23:34:38 +00:00
Register * s = acquire ( c , mask , stack , locals , r - > size , r - > value , r - > site ) ;
2008-09-27 22:01:39 +00:00
thaw ( c , r ) ;
2008-05-15 20:00:57 +00:00
2008-05-18 01:26:36 +00:00
if ( DebugRegisters ) {
fprintf ( stderr , " replace %d with %d \n " , r - > number , s - > number ) ;
}
2008-05-12 13:54:47 +00:00
swap ( c , r , s ) ;
2008-05-15 20:00:57 +00:00
2008-05-12 13:54:47 +00:00
return s ;
}
Register *
2008-09-24 00:01:42 +00:00
acquire ( Context * c , uint32_t mask , Stack * stack , Local * locals ,
2008-07-17 23:34:38 +00:00
unsigned newSize , Value * newValue , RegisterSite * newSite )
2008-04-17 22:07:32 +00:00
{
2008-05-12 13:54:47 +00:00
Register * r = pickRegister ( c , mask ) ;
if ( r - > reserved ) return r ;
2008-04-19 00:19:45 +00:00
2008-04-20 00:43:12 +00:00
if ( DebugRegisters ) {
2008-10-04 17:26:35 +00:00
fprintf ( stderr , " acquire %d value %p site %p freeze count %d "
2008-07-17 23:34:38 +00:00
" ref count %d used %d used exclusively %d \n " ,
r - > number , newValue , newSite , r - > freezeCount , r - > refCount ,
used ( c , r ) , usedExclusively ( c , r ) ) ;
2008-04-20 00:43:12 +00:00
}
2008-04-19 00:19:45 +00:00
2008-05-12 13:54:47 +00:00
if ( r - > refCount ) {
2008-08-28 22:43:35 +00:00
r = replace ( c , stack , locals , r ) ;
2008-05-12 13:54:47 +00:00
} else {
Value * oldValue = r - > value ;
if ( oldValue
and oldValue ! = newValue
and findSite ( c , oldValue , r - > site ) )
{
2008-07-17 23:34:38 +00:00
if ( not trySteal ( c , r , stack , locals ) ) {
2008-08-28 22:43:35 +00:00
r = replace ( c , stack , locals , r ) ;
2008-05-12 13:54:47 +00:00
}
2008-04-17 22:07:32 +00:00
}
}
2008-05-12 13:54:47 +00:00
r - > size = newSize ;
r - > value = newValue ;
r - > site = newSite ;
2008-04-21 00:21:48 +00:00
2008-05-12 13:54:47 +00:00
return r ;
2008-04-17 22:07:32 +00:00
}
2008-04-19 00:19:45 +00:00
void
2008-05-12 13:54:47 +00:00
release ( Context * , Register * r )
2008-04-19 00:19:45 +00:00
{
2008-04-20 00:43:12 +00:00
if ( DebugRegisters ) {
2008-05-12 13:54:47 +00:00
fprintf ( stderr , " release %d \n " , r - > number ) ;
2008-04-20 00:43:12 +00:00
}
2008-05-12 13:54:47 +00:00
r - > size = 0 ;
r - > value = 0 ;
r - > site = 0 ;
2008-04-19 00:19:45 +00:00
}
2008-05-15 20:00:57 +00:00
Register *
2008-09-24 00:01:42 +00:00
validate ( Context * c , uint32_t mask , Stack * stack , Local * locals ,
2008-07-17 23:34:38 +00:00
unsigned size , Value * value , RegisterSite * site , Register * current )
2008-05-15 20:00:57 +00:00
{
2008-05-15 23:19:23 +00:00
if ( current and ( mask & ( 1 < < current - > number ) ) ) {
if ( current - > reserved or current - > value = = value ) {
return current ;
}
if ( current - > value = = 0 ) {
2008-10-04 17:26:35 +00:00
if ( DebugRegisters ) {
fprintf ( stderr ,
" validate acquire %d value %p site %p freeze count %d "
" ref count %d \n " ,
current - > number , value , site , current - > freezeCount ,
current - > refCount ) ;
}
2008-05-15 23:19:23 +00:00
current - > size = size ;
current - > value = value ;
current - > site = site ;
return current ;
}
}
2008-07-17 23:34:38 +00:00
Register * r = acquire ( c , mask , stack , locals , size , value , site ) ;
2008-05-15 23:19:23 +00:00
if ( current and current ! = r ) {
2008-05-15 20:00:57 +00:00
release ( c , current ) ;
Assembler : : Register rr ( r - > number ) ;
Assembler : : Register cr ( current - > number ) ;
c - > assembler - > apply
2008-08-16 17:45:36 +00:00
( Move , BytesPerWord , RegisterOperand , & cr ,
BytesPerWord , RegisterOperand , & rr ) ;
2008-05-15 20:00:57 +00:00
}
2008-05-15 23:19:23 +00:00
return r ;
2008-05-15 20:00:57 +00:00
}
2008-09-28 21:56:12 +00:00
bool
2008-10-17 00:10:35 +00:00
trySteal ( Context * c , FrameResource * r , Stack * stack , Local * locals )
2008-09-28 21:56:12 +00:00
{
2008-11-01 22:16:18 +00:00
assert ( c , live ( r - > value ) ) ;
2008-10-04 17:26:35 +00:00
if ( DebugFrameIndexes ) {
int index = r - c - > frameResources ;
fprintf ( stderr ,
2008-10-17 00:10:35 +00:00
" try steal frame index %d offset 0x%x from value %p site %p \n " ,
2008-10-25 02:12:02 +00:00
index , frameIndexToOffset ( c , index ) , r - > value , r - > site ) ;
2008-09-28 21:56:12 +00:00
}
2008-10-17 00:10:35 +00:00
return trySteal ( c , r - > site , r - > value , r - > size , stack , locals ) ;
2008-09-28 21:56:12 +00:00
}
void
2008-10-25 02:12:02 +00:00
acquireFrameIndex ( Context * c , int frameIndex , Stack * stack , Local * locals ,
2008-09-28 21:56:12 +00:00
unsigned newSize , Value * newValue , MemorySite * newSite ,
bool recurse )
{
2008-10-25 02:12:02 +00:00
assert ( c , frameIndex > = 0 ) ;
assert ( c , frameIndex < static_cast < int >
2008-09-28 21:56:12 +00:00
( c - > alignedFrameSize + c - > parameterFootprint ) ) ;
2008-10-04 17:26:35 +00:00
if ( DebugFrameIndexes ) {
fprintf ( stderr ,
" acquire frame index %d offset 0x%x value %p site %p \n " ,
2008-10-25 02:12:02 +00:00
frameIndex , frameIndexToOffset ( c , frameIndex ) , newValue , newSite ) ;
2008-10-04 17:26:35 +00:00
}
2008-10-25 02:12:02 +00:00
FrameResource * r = c - > frameResources + frameIndex ;
2008-09-28 21:56:12 +00:00
if ( recurse and newSize > BytesPerWord ) {
acquireFrameIndex
2008-10-25 02:12:02 +00:00
( c , frameIndex + 1 , stack , locals , newSize , newValue , newSite , false ) ;
2008-09-28 21:56:12 +00:00
}
Value * oldValue = r - > value ;
if ( oldValue
and oldValue ! = newValue
and findSite ( c , oldValue , r - > site ) )
{
if ( not trySteal ( c , r , stack , locals ) ) {
abort ( c ) ;
}
}
r - > size = newSize ;
r - > value = newValue ;
2008-10-04 17:26:35 +00:00
r - > site = newSite ;
2008-09-28 21:56:12 +00:00
}
void
2008-10-25 02:12:02 +00:00
releaseFrameIndex ( Context * c , int frameIndex , bool recurse )
2008-09-28 21:56:12 +00:00
{
2008-10-25 02:12:02 +00:00
assert ( c , frameIndex > = 0 ) ;
assert ( c , frameIndex < static_cast < int >
2008-09-28 21:56:12 +00:00
( c - > alignedFrameSize + c - > parameterFootprint ) ) ;
2008-10-04 17:26:35 +00:00
if ( DebugFrameIndexes ) {
fprintf ( stderr , " release frame index %d offset 0x%x \n " ,
2008-10-25 02:12:02 +00:00
frameIndex , frameIndexToOffset ( c , frameIndex ) ) ;
2008-10-04 17:26:35 +00:00
}
2008-10-25 02:12:02 +00:00
FrameResource * r = c - > frameResources + frameIndex ;
2008-09-28 21:56:12 +00:00
if ( recurse and r - > size > BytesPerWord ) {
2008-10-25 02:12:02 +00:00
releaseFrameIndex ( c , frameIndex + 1 , false ) ;
2008-09-28 21:56:12 +00:00
}
r - > size = 0 ;
r - > value = 0 ;
r - > site = 0 ;
}
2008-04-17 02:55:38 +00:00
void
2008-08-16 17:45:36 +00:00
apply ( Context * c , UnaryOperation op ,
unsigned s1Size , Site * s1 )
{
OperandType s1Type = s1 - > type ( c ) ;
Assembler : : Operand * s1Operand = s1 - > asAssemblerOperand ( c ) ;
c - > assembler - > apply ( op , s1Size , s1Type , s1Operand ) ;
}
void
apply ( Context * c , BinaryOperation op ,
unsigned s1Size , Site * s1 ,
unsigned s2Size , Site * s2 )
2008-04-17 02:55:38 +00:00
{
2008-08-16 17:45:36 +00:00
OperandType s1Type = s1 - > type ( c ) ;
Assembler : : Operand * s1Operand = s1 - > asAssemblerOperand ( c ) ;
OperandType s2Type = s2 - > type ( c ) ;
Assembler : : Operand * s2Operand = s2 - > asAssemblerOperand ( c ) ;
2008-03-15 20:24:04 +00:00
2008-08-16 17:45:36 +00:00
c - > assembler - > apply ( op , s1Size , s1Type , s1Operand ,
s2Size , s2Type , s2Operand ) ;
2008-04-17 02:55:38 +00:00
}
2008-02-17 20:57:40 +00:00
2008-04-17 02:55:38 +00:00
void
2008-08-16 17:45:36 +00:00
apply ( Context * c , TernaryOperation op ,
unsigned s1Size , Site * s1 ,
unsigned s2Size , Site * s2 ,
unsigned s3Size , Site * s3 )
2008-04-17 02:55:38 +00:00
{
2008-08-16 17:45:36 +00:00
OperandType s1Type = s1 - > type ( c ) ;
Assembler : : Operand * s1Operand = s1 - > asAssemblerOperand ( c ) ;
2008-02-17 20:57:40 +00:00
2008-08-16 17:45:36 +00:00
OperandType s2Type = s2 - > type ( c ) ;
Assembler : : Operand * s2Operand = s2 - > asAssemblerOperand ( c ) ;
2008-02-17 22:29:04 +00:00
2008-08-16 17:45:36 +00:00
OperandType s3Type = s3 - > type ( c ) ;
Assembler : : Operand * s3Operand = s3 - > asAssemblerOperand ( c ) ;
c - > assembler - > apply ( op , s1Size , s1Type , s1Operand ,
s2Size , s2Type , s2Operand ,
s3Size , s3Type , s3Operand ) ;
2008-04-17 02:55:38 +00:00
}
2008-02-17 20:57:40 +00:00
2008-03-11 16:40:28 +00:00
void
2008-09-15 02:28:42 +00:00
addRead ( Context * c , Event * e , Value * v , Read * r )
2008-03-11 16:40:28 +00:00
{
2008-11-01 19:14:13 +00:00
fprintf ( stderr , " add read %p to %p last %p event %p (%s) \n " , r , v , v - > lastRead , e , ( e ? e - > name ( ) : 0 ) ) ;
2008-09-25 00:48:32 +00:00
2008-08-28 22:43:35 +00:00
r - > value = v ;
2008-09-15 02:28:42 +00:00
if ( e ) {
r - > event = e ;
r - > eventNext = e - > reads ;
e - > reads = r ;
+ + e - > readCount ;
}
2008-04-17 02:55:38 +00:00
2008-09-13 21:09:26 +00:00
if ( v - > lastRead ) {
2008-09-15 02:28:42 +00:00
//fprintf(stderr, "append %p to %p for %p\n", r, v->lastRead, v);
2008-09-13 21:09:26 +00:00
v - > lastRead - > append ( c , r ) ;
} else {
v - > reads = r ;
2008-04-17 02:55:38 +00:00
}
2008-09-13 21:09:26 +00:00
v - > lastRead = r ;
2008-03-11 16:40:28 +00:00
}
2008-07-05 20:21:13 +00:00
void
2008-10-06 00:50:59 +00:00
clean ( Context * c , Value * v , unsigned popIndex )
2008-07-05 20:21:13 +00:00
{
2008-11-01 22:16:18 +00:00
for ( SiteIterator it ( v ) ; it . hasMore ( ) ; ) {
Site * s = it . next ( ) ;
if ( not ( s - > match ( c , 1 < < MemoryOperand , 0 , AnyFrameIndex )
and offsetToFrameIndex
( c , static_cast < MemorySite * > ( s ) - > value . offset )
> = popIndex ) )
2008-10-06 00:50:59 +00:00
{
2008-11-01 22:16:18 +00:00
char buffer [ 256 ] ; s - > toString ( c , buffer , 256 ) ;
fprintf ( stderr , " remove %s from %p at %d pop index %d \n " ,
buffer , v , offsetToFrameIndex
( c , static_cast < MemorySite * > ( s ) - > value . offset ) , popIndex ) ;
it . remove ( c ) ;
2008-07-05 20:21:13 +00:00
}
}
}
2008-04-17 22:07:32 +00:00
void
2008-10-06 00:50:59 +00:00
clean ( Context * c , Event * e , Stack * stack , Local * locals , Read * reads ,
unsigned popIndex )
2008-05-19 04:31:52 +00:00
{
2008-11-01 19:14:13 +00:00
for ( FrameIterator it ( c , stack , locals ) ; it . hasMore ( ) ; ) {
FrameIterator : : Element e = it . next ( c ) ;
clean ( c , e . value , popIndex ) ;
2008-05-19 04:31:52 +00:00
}
for ( Read * r = reads ; r ; r = r - > eventNext ) {
2008-09-25 00:48:32 +00:00
nextRead ( c , e , r - > value ) ;
2008-08-28 22:43:35 +00:00
}
2008-05-19 04:31:52 +00:00
}
2008-05-31 22:24:04 +00:00
CodePromise *
codePromise ( Context * c , Event * e )
{
return e - > promises = new ( c - > zone - > allocate ( sizeof ( CodePromise ) ) )
CodePromise ( c , e - > promises ) ;
}
CodePromise *
2008-09-09 00:31:19 +00:00
codePromise ( Context * c , Promise * offset )
2008-05-31 22:24:04 +00:00
{
return new ( c - > zone - > allocate ( sizeof ( CodePromise ) ) ) CodePromise ( c , offset ) ;
}
2008-10-14 00:18:18 +00:00
void
append ( Context * c , Event * e ) ;
2008-04-17 02:55:38 +00:00
class CallEvent : public Event {
2008-02-11 17:21:41 +00:00
public :
2008-05-06 21:13:02 +00:00
CallEvent ( Context * c , Value * address , unsigned flags ,
2008-04-18 04:16:20 +00:00
TraceHandler * traceHandler , Value * result , unsigned resultSize ,
2008-08-23 18:04:36 +00:00
Stack * argumentStack , unsigned argumentCount ,
unsigned stackArgumentFootprint ) :
2008-04-17 02:55:38 +00:00
Event ( c ) ,
address ( address ) ,
traceHandler ( traceHandler ) ,
2008-04-17 20:48:26 +00:00
result ( result ) ,
2008-10-25 02:12:02 +00:00
popIndex ( 0 ) ,
2008-04-17 20:48:26 +00:00
flags ( flags ) ,
2008-08-23 18:04:36 +00:00
resultSize ( resultSize )
2008-02-17 20:57:40 +00:00
{
2008-05-15 20:00:57 +00:00
uint32_t mask = ~ 0 ;
2008-04-19 00:19:45 +00:00
Stack * s = argumentStack ;
2008-04-21 00:21:48 +00:00
unsigned index = 0 ;
2008-10-25 02:12:02 +00:00
unsigned frameIndex = 0 ;
2008-04-19 00:19:45 +00:00
for ( unsigned i = 0 ; i < argumentCount ; + + i ) {
2008-08-23 18:04:36 +00:00
Read * target ;
2008-08-28 22:43:35 +00:00
if ( index < c - > arch - > argumentRegisterCount ( ) ) {
int r = c - > arch - > argumentRegister ( index ) ;
2008-10-25 02:12:02 +00:00
fprintf ( stderr , " reg %d arg read %p \n " , r , s - > value ) ;
2008-11-01 19:14:13 +00:00
target = fixedRegisterRead ( c , s - > sizeInWords * BytesPerWord , r ) ;
2008-05-15 20:00:57 +00:00
mask & = ~ ( 1 < < r ) ;
2008-04-19 00:19:45 +00:00
} else {
2008-11-01 19:14:13 +00:00
fprintf ( stderr , " stack %d arg read %p \n " , frameIndex , s - > value ) ;
target = read ( c , s - > sizeInWords * BytesPerWord , 1 < < MemoryOperand , 0 ,
2008-08-28 22:43:35 +00:00
frameIndex ) ;
2008-11-01 19:14:13 +00:00
frameIndex + = s - > sizeInWords ;
2008-04-19 00:19:45 +00:00
}
2008-09-15 02:28:42 +00:00
addRead ( c , this , s - > value , target ) ;
2008-11-01 19:14:13 +00:00
index + = s - > sizeInWords ;
2008-04-19 00:19:45 +00:00
s = s - > next ;
}
2008-11-01 19:14:13 +00:00
fprintf ( stderr , " address read %p \n " , address ) ;
2008-09-15 02:28:42 +00:00
addRead ( c , this , address , read
2008-08-28 22:43:35 +00:00
( c , BytesPerWord , ~ 0 , ( static_cast < uint64_t > ( mask ) < < 32 ) | mask ,
2008-08-23 18:04:36 +00:00
AnyFrameIndex ) ) ;
2008-05-15 20:00:57 +00:00
2008-08-23 18:04:36 +00:00
int footprint = stackArgumentFootprint ;
2008-10-04 17:26:35 +00:00
for ( Stack * s = stackBefore ; s ; s = s - > next ) {
2008-09-23 21:18:41 +00:00
if ( footprint > 0 ) {
2008-11-01 19:14:13 +00:00
fprintf ( stderr , " stack arg read %p of size %d at %d of %d \n " , s - > value , s - > sizeInWords , frameIndex , c - > alignedFrameSize + c - > parameterFootprint ) ;
2008-09-25 00:48:32 +00:00
addRead ( c , this , s - > value , read
2008-11-01 19:14:13 +00:00
( c , s - > sizeInWords * BytesPerWord ,
2008-09-25 00:48:32 +00:00
1 < < MemoryOperand , 0 , frameIndex ) ) ;
2008-10-06 00:50:59 +00:00
} else {
2008-10-25 02:12:02 +00:00
unsigned index = : : frameIndex
2008-11-01 19:14:13 +00:00
( c , s - > index + c - > localFootprint , s - > sizeInWords ) ;
2008-08-23 18:04:36 +00:00
if ( footprint = = 0 ) {
2008-10-25 02:12:02 +00:00
assert ( c , index > = frameIndex ) ;
2008-11-01 19:14:13 +00:00
s - > paddingInWords = index - frameIndex ;
2008-10-25 02:12:02 +00:00
popIndex = index ;
2008-08-23 18:04:36 +00:00
}
2008-11-01 19:14:13 +00:00
fprintf ( stderr , " stack save read %p of size %d at %d of %d \n " , s - > value , s - > sizeInWords , index , c - > alignedFrameSize + c - > parameterFootprint ) ;
2008-09-23 21:18:41 +00:00
addRead ( c , this , s - > value , read
2008-11-01 19:14:13 +00:00
( c , s - > sizeInWords * BytesPerWord , 1 < < MemoryOperand , 0 , index ) ) ;
2008-08-23 18:04:36 +00:00
}
2008-11-01 19:14:13 +00:00
frameIndex + = s - > sizeInWords ;
footprint - = s - > sizeInWords ;
2008-05-15 20:00:57 +00:00
}
2008-09-25 00:48:32 +00:00
2008-10-25 02:12:02 +00:00
for ( unsigned li = 0 ; li < c - > localFootprint ; + + li ) {
Local * local = localsBefore + li ;
2008-09-25 00:48:32 +00:00
if ( local - > value ) {
2008-11-01 19:14:13 +00:00
fprintf ( stderr , " local save read %p of size %d at %d of %d \n " , local - > value , local - > sizeInBytes , : : frameIndex ( c , li , ceiling ( local - > sizeInBytes , BytesPerWord ) ) , c - > alignedFrameSize + c - > parameterFootprint ) ;
2008-09-25 00:48:32 +00:00
addRead ( c , this , local - > value , read
2008-11-01 19:14:13 +00:00
( c , local - > sizeInBytes , 1 < < MemoryOperand , 0 ,
: : frameIndex
( c , li , ceiling ( local - > sizeInBytes , BytesPerWord ) ) ) ) ;
2008-09-25 00:48:32 +00:00
}
}
2008-02-11 17:21:41 +00:00
}
2007-12-12 22:19:13 +00:00
2008-09-15 02:28:42 +00:00
virtual const char * name ( ) {
return " CallEvent " ;
}
2008-02-11 17:21:41 +00:00
virtual void compile ( Context * c ) {
2008-08-23 18:04:36 +00:00
apply ( c , ( flags & Compiler : : Aligned ) ? AlignedCall : Call , BytesPerWord ,
address - > source ) ;
2007-12-12 22:19:13 +00:00
2008-05-15 23:19:23 +00:00
if ( traceHandler ) {
2008-08-30 20:12:27 +00:00
traceHandler - > handleTrace ( codePromise ( c , c - > assembler - > offset ( ) ) ) ;
2008-05-15 23:19:23 +00:00
}
2008-10-06 00:50:59 +00:00
clean ( c , this , stackBefore , localsBefore , reads , popIndex ) ;
2008-04-19 00:19:45 +00:00
2008-07-05 20:21:13 +00:00
if ( resultSize and live ( result ) ) {
2008-07-17 23:34:38 +00:00
addSite ( c , 0 , 0 , resultSize , result , registerSite
2008-08-28 22:43:35 +00:00
( c , c - > arch - > returnLow ( ) ,
2008-04-19 00:19:45 +00:00
resultSize > BytesPerWord ?
2008-08-28 22:43:35 +00:00
c - > arch - > returnHigh ( ) : NoRegister ) ) ;
2008-04-19 00:19:45 +00:00
}
2008-02-11 17:21:41 +00:00
}
2007-12-23 18:48:22 +00:00
2008-04-17 02:55:38 +00:00
Value * address ;
TraceHandler * traceHandler ;
Value * result ;
2008-10-06 00:50:59 +00:00
unsigned popIndex ;
2008-04-17 20:48:26 +00:00
unsigned flags ;
2008-04-18 04:16:20 +00:00
unsigned resultSize ;
2008-02-11 17:21:41 +00:00
} ;
2007-12-12 22:19:13 +00:00
2008-02-11 17:21:41 +00:00
void
2008-05-06 21:13:02 +00:00
appendCall ( Context * c , Value * address , unsigned flags ,
2008-04-18 04:16:20 +00:00
TraceHandler * traceHandler , Value * result , unsigned resultSize ,
2008-08-23 18:04:36 +00:00
Stack * argumentStack , unsigned argumentCount ,
unsigned stackArgumentFootprint )
2008-02-11 17:21:41 +00:00
{
2008-10-14 00:18:18 +00:00
append ( c , new ( c - > zone - > allocate ( sizeof ( CallEvent ) ) )
CallEvent ( c , address , flags , traceHandler , result ,
resultSize , argumentStack , argumentCount ,
stackArgumentFootprint ) ) ;
2008-02-11 17:21:41 +00:00
}
2007-12-23 18:48:22 +00:00
2008-04-17 02:55:38 +00:00
class ReturnEvent : public Event {
2008-02-17 20:57:40 +00:00
public :
2008-04-17 02:55:38 +00:00
ReturnEvent ( Context * c , unsigned size , Value * value ) :
Event ( c ) , value ( value )
{
if ( value ) {
2008-09-15 02:28:42 +00:00
addRead ( c , this , value , fixedRegisterRead
2008-08-28 22:43:35 +00:00
( c , size , c - > arch - > returnLow ( ) ,
2008-04-17 02:55:38 +00:00
size > BytesPerWord ?
2008-08-28 22:43:35 +00:00
c - > arch - > returnHigh ( ) : NoRegister ) ) ;
2008-04-17 02:55:38 +00:00
}
2008-03-15 20:24:04 +00:00
}
2008-09-15 02:28:42 +00:00
virtual const char * name ( ) {
return " ReturnEvent " ;
}
2008-02-17 20:57:40 +00:00
2008-09-15 02:28:42 +00:00
virtual void compile ( Context * c ) {
2008-04-19 00:19:45 +00:00
if ( value ) {
2008-09-25 00:48:32 +00:00
nextRead ( c , this , value ) ;
2008-04-19 00:19:45 +00:00
}
2008-08-28 22:43:35 +00:00
c - > assembler - > popFrame ( ) ;
2008-04-17 02:55:38 +00:00
c - > assembler - > apply ( Return ) ;
2008-02-17 20:57:40 +00:00
}
2008-04-17 02:55:38 +00:00
Value * value ;
2008-02-17 20:57:40 +00:00
} ;
void
2008-04-17 22:07:32 +00:00
appendReturn ( Context * c , unsigned size , Value * value )
2008-02-17 20:57:40 +00:00
{
2008-10-14 00:18:18 +00:00
append ( c , new ( c - > zone - > allocate ( sizeof ( ReturnEvent ) ) )
ReturnEvent ( c , size , value ) ) ;
2008-02-17 20:57:40 +00:00
}
2008-10-25 02:12:02 +00:00
void
preserve ( Context * c , Stack * stack , Local * locals , unsigned size , Value * v ,
Site * s , Read * read )
{
2008-11-01 19:14:13 +00:00
Site * r = targetOrRegister ( c , v , read ) ;
2008-10-25 02:12:02 +00:00
move ( c , stack , locals , size , v , s , r ) ;
}
void
maybePreserve ( Context * c , Stack * stack , Local * locals , unsigned size ,
Value * v , Site * s )
{
2008-11-01 22:16:18 +00:00
Read * r = liveNext ( c , v ) ;
if ( r and not hasMoreThanOneSite ( v ) ) {
preserve ( c , stack , locals , size , v , s , r ) ;
2008-10-25 02:12:02 +00:00
}
}
2008-04-17 02:55:38 +00:00
class MoveEvent : public Event {
2008-02-11 17:21:41 +00:00
public :
2008-08-16 17:45:36 +00:00
MoveEvent ( Context * c , BinaryOperation type , unsigned srcSize , Value * src ,
2008-08-28 22:43:35 +00:00
unsigned dstSize , Value * dst , Read * srcRead , Read * dstRead ) :
2008-08-16 17:45:36 +00:00
Event ( c ) , type ( type ) , srcSize ( srcSize ) , src ( src ) , dstSize ( dstSize ) ,
2008-08-28 22:43:35 +00:00
dst ( dst ) , dstRead ( dstRead )
2008-02-17 20:57:40 +00:00
{
2008-09-15 02:28:42 +00:00
addRead ( c , this , src , srcRead ) ;
2008-03-15 20:24:04 +00:00
}
2008-09-15 02:28:42 +00:00
virtual const char * name ( ) {
return " MoveEvent " ;
}
2008-03-15 20:24:04 +00:00
2008-09-15 02:28:42 +00:00
virtual void compile ( Context * c ) {
2008-11-01 19:14:13 +00:00
bool isStore = not live ( dst ) ;
2008-05-19 13:44:39 +00:00
2008-07-05 20:21:13 +00:00
Site * target = targetOrRegister ( c , dst ) ;
unsigned cost = src - > source - > copyCost ( c , target ) ;
2008-10-19 00:15:57 +00:00
if ( cost = = 0 ) {
2008-04-18 17:30:54 +00:00
target = src - > source ;
2008-10-25 02:12:02 +00:00
char dstb [ 256 ] ; target - > toString ( c , dstb , 256 ) ;
fprintf ( stderr , " null move in %s for %p to %p \n " , dstb , src , dst ) ;
2008-04-18 17:00:55 +00:00
}
2008-04-19 00:19:45 +00:00
2008-05-18 01:26:36 +00:00
if ( target = = src - > source ) {
2008-10-25 02:12:02 +00:00
maybePreserve ( c , stackBefore , localsBefore , srcSize , src , target ) ;
2008-05-19 14:53:40 +00:00
removeSite ( c , src , target ) ;
2008-05-18 01:26:36 +00:00
}
2008-04-19 00:19:45 +00:00
2008-05-19 04:31:52 +00:00
if ( not isStore ) {
2008-10-04 17:26:35 +00:00
addSite ( c , stackBefore , localsBefore , dstSize , dst , target ) ;
2008-04-28 22:08:31 +00:00
}
2008-08-28 22:43:35 +00:00
if ( cost or type ! = Move ) {
uint8_t typeMask = ~ static_cast < uint8_t > ( 0 ) ;
uint64_t registerMask = ~ static_cast < uint64_t > ( 0 ) ;
int frameIndex = AnyFrameIndex ;
dstRead - > intersect ( & typeMask , & registerMask , & frameIndex ) ;
2008-10-04 17:26:35 +00:00
bool memoryToMemory = ( target - > type ( c ) = = MemoryOperand
and src - > source - > type ( c ) = = MemoryOperand ) ;
if ( target - > match ( c , typeMask , registerMask , frameIndex )
and not memoryToMemory )
{
2008-10-19 00:15:57 +00:00
char srcb [ 256 ] ; src - > source - > toString ( c , srcb , 256 ) ;
char dstb [ 256 ] ; target - > toString ( c , dstb , 256 ) ;
fprintf ( stderr , " move %s to %s for %p to %p \n " , srcb , dstb , src , dst ) ;
2008-08-16 17:45:36 +00:00
apply ( c , type , srcSize , src - > source , dstSize , target ) ;
2008-05-16 16:01:24 +00:00
} else {
2008-08-28 22:43:35 +00:00
assert ( c , typeMask & ( 1 < < RegisterOperand ) ) ;
2008-05-16 16:01:24 +00:00
2008-08-28 22:43:35 +00:00
Site * tmpTarget = freeRegisterSite ( c , registerMask ) ;
2008-05-16 16:01:24 +00:00
2008-10-04 17:26:35 +00:00
addSite ( c , stackBefore , localsBefore , dstSize , dst , tmpTarget ) ;
2008-05-16 16:01:24 +00:00
2008-10-19 00:15:57 +00:00
char srcb [ 256 ] ; src - > source - > toString ( c , srcb , 256 ) ;
char dstb [ 256 ] ; tmpTarget - > toString ( c , dstb , 256 ) ;
fprintf ( stderr , " move %s to %s for %p to %p \n " , srcb , dstb , src , dst ) ;
2008-08-16 17:45:36 +00:00
apply ( c , type , srcSize , src - > source , dstSize , tmpTarget ) ;
2008-05-16 16:01:24 +00:00
2008-05-19 04:31:52 +00:00
if ( isStore ) {
2008-05-18 01:26:36 +00:00
removeSite ( c , dst , tmpTarget ) ;
2008-10-04 17:26:35 +00:00
}
2008-05-18 01:26:36 +00:00
2008-10-04 17:26:35 +00:00
if ( memoryToMemory or isStore ) {
2008-10-19 00:15:57 +00:00
char srcb [ 256 ] ; tmpTarget - > toString ( c , srcb , 256 ) ;
char dstb [ 256 ] ; target - > toString ( c , dstb , 256 ) ;
fprintf ( stderr , " move %s to %s for %p to %p \n " , srcb , dstb , src , dst ) ;
2008-08-16 17:45:36 +00:00
apply ( c , Move , dstSize , tmpTarget , dstSize , target ) ;
2008-05-18 01:26:36 +00:00
} else {
removeSite ( c , dst , target ) ;
}
2008-05-16 16:01:24 +00:00
}
2008-04-27 20:15:18 +00:00
}
2008-05-19 04:31:52 +00:00
if ( isStore ) {
2008-04-20 19:35:36 +00:00
removeSite ( c , dst , target ) ;
}
2008-05-18 01:26:36 +00:00
2008-09-25 00:48:32 +00:00
nextRead ( c , this , src ) ;
2007-12-11 21:26:59 +00:00
}
2008-04-17 02:55:38 +00:00
BinaryOperation type ;
2008-08-16 17:45:36 +00:00
unsigned srcSize ;
2008-04-17 02:55:38 +00:00
Value * src ;
2008-08-16 17:45:36 +00:00
unsigned dstSize ;
2008-04-17 02:55:38 +00:00
Value * dst ;
2008-08-28 22:43:35 +00:00
Read * dstRead ;
2008-02-11 17:21:41 +00:00
} ;
2007-12-11 21:26:59 +00:00
void
2008-08-28 22:43:35 +00:00
appendMove ( Context * c , BinaryOperation type , unsigned srcSize , Value * src ,
unsigned dstSize , Value * dst )
2007-12-11 21:26:59 +00:00
{
2008-05-31 22:14:27 +00:00
bool thunk ;
2008-08-28 22:43:35 +00:00
uint8_t srcTypeMask ;
uint64_t srcRegisterMask ;
uint8_t dstTypeMask ;
uint64_t dstRegisterMask ;
2008-05-04 20:55:34 +00:00
2008-08-28 22:43:35 +00:00
c - > arch - > plan ( type , srcSize , & srcTypeMask , & srcRegisterMask ,
dstSize , & dstTypeMask , & dstRegisterMask ,
& thunk ) ;
2008-05-04 20:55:34 +00:00
2008-05-31 22:14:27 +00:00
assert ( c , not thunk ) ; // todo
2008-05-04 20:55:34 +00:00
2008-10-14 00:18:18 +00:00
append ( c , new ( c - > zone - > allocate ( sizeof ( MoveEvent ) ) )
MoveEvent
( c , type , srcSize , src , dstSize , dst ,
read ( c , srcSize , srcTypeMask , srcRegisterMask , AnyFrameIndex ) ,
read ( c , dstSize , dstTypeMask , dstRegisterMask , AnyFrameIndex ) ) ) ;
2008-02-11 17:21:41 +00:00
}
2007-12-20 01:42:12 +00:00
2008-06-11 00:17:44 +00:00
ConstantSite *
findConstantSite ( Context * c , Value * v )
{
2008-11-01 22:16:18 +00:00
for ( SiteIterator it ( v ) ; it . hasMore ( ) ; ) {
Site * s = it . next ( ) ;
2008-06-11 00:17:44 +00:00
if ( s - > type ( c ) = = ConstantOperand ) {
return static_cast < ConstantSite * > ( s ) ;
}
}
return 0 ;
}
2008-04-17 02:55:38 +00:00
class CompareEvent : public Event {
2008-02-11 17:21:41 +00:00
public :
2008-05-19 13:27:05 +00:00
CompareEvent ( Context * c , unsigned size , Value * first , Value * second ,
2008-08-28 22:43:35 +00:00
Read * firstRead , Read * secondRead ) :
2008-04-17 02:55:38 +00:00
Event ( c ) , size ( size ) , first ( first ) , second ( second )
2008-02-17 20:57:40 +00:00
{
2008-09-15 02:28:42 +00:00
addRead ( c , this , first , firstRead ) ;
addRead ( c , this , second , secondRead ) ;
2008-02-11 17:21:41 +00:00
}
2007-12-20 01:42:12 +00:00
2008-09-15 02:28:42 +00:00
virtual const char * name ( ) {
return " CompareEvent " ;
}
2008-03-15 20:24:04 +00:00
2008-09-15 02:28:42 +00:00
virtual void compile ( Context * c ) {
2008-06-11 00:17:44 +00:00
ConstantSite * firstConstant = findConstantSite ( c , first ) ;
ConstantSite * secondConstant = findConstantSite ( c , second ) ;
if ( firstConstant and secondConstant ) {
int64_t d = firstConstant - > value . value - > value ( )
- secondConstant - > value . value - > value ( ) ;
if ( d < 0 ) {
c - > constantCompare = CompareLess ;
} else if ( d > 0 ) {
c - > constantCompare = CompareGreater ;
} else {
c - > constantCompare = CompareEqual ;
}
} else {
c - > constantCompare = CompareNone ;
2008-08-16 17:45:36 +00:00
apply ( c , Compare , size , first - > source , size , second - > source ) ;
2008-06-11 00:17:44 +00:00
}
2008-04-19 00:19:45 +00:00
2008-09-25 00:48:32 +00:00
nextRead ( c , this , first ) ;
nextRead ( c , this , second ) ;
2007-12-11 21:26:59 +00:00
}
2008-02-11 17:21:41 +00:00
2008-04-17 02:55:38 +00:00
unsigned size ;
Value * first ;
Value * second ;
2008-02-11 17:21:41 +00:00
} ;
2007-12-11 21:26:59 +00:00
void
2008-04-17 02:55:38 +00:00
appendCompare ( Context * c , unsigned size , Value * first , Value * second )
2007-12-11 21:26:59 +00:00
{
2008-05-31 22:14:27 +00:00
bool thunk ;
2008-08-28 22:43:35 +00:00
uint8_t firstTypeMask ;
uint64_t firstRegisterMask ;
uint8_t secondTypeMask ;
uint64_t secondRegisterMask ;
2008-05-19 13:27:05 +00:00
2008-08-28 22:43:35 +00:00
c - > arch - > plan ( Compare , size , & firstTypeMask , & firstRegisterMask ,
size , & secondTypeMask , & secondRegisterMask ,
& thunk ) ;
2008-05-19 13:27:05 +00:00
2008-05-31 22:14:27 +00:00
assert ( c , not thunk ) ; // todo
2008-05-19 13:27:05 +00:00
2008-10-14 00:18:18 +00:00
append ( c , new ( c - > zone - > allocate ( sizeof ( CompareEvent ) ) )
CompareEvent
( c , size , first , second ,
read ( c , size , firstTypeMask , firstRegisterMask , AnyFrameIndex ) ,
read ( c , size , secondTypeMask , secondRegisterMask , AnyFrameIndex ) ) ) ;
2008-02-11 17:21:41 +00:00
}
class CombineEvent : public Event {
public :
2008-08-16 17:45:36 +00:00
CombineEvent ( Context * c , TernaryOperation type ,
unsigned firstSize , Value * first ,
unsigned secondSize , Value * second ,
unsigned resultSize , Value * result ,
2008-09-07 20:12:11 +00:00
Read * firstRead ,
Read * secondRead ,
Read * resultRead ) :
2008-08-16 17:45:36 +00:00
Event ( c ) , type ( type ) , firstSize ( firstSize ) , first ( first ) ,
secondSize ( secondSize ) , second ( second ) , resultSize ( resultSize ) ,
2008-09-07 20:12:11 +00:00
result ( result ) , resultRead ( resultRead )
2008-02-17 20:57:40 +00:00
{
2008-09-15 02:28:42 +00:00
addRead ( c , this , first , firstRead ) ;
addRead ( c , this , second , secondRead ) ;
2008-02-11 17:21:41 +00:00
}
2007-12-16 23:52:38 +00:00
2008-09-15 02:28:42 +00:00
virtual const char * name ( ) {
return " CombineEvent " ;
}
2008-02-17 20:57:40 +00:00
2008-09-15 02:28:42 +00:00
virtual void compile ( Context * c ) {
2008-09-07 20:12:11 +00:00
Site * target ;
if ( c - > arch - > condensedAddressing ( ) ) {
2008-10-04 17:26:35 +00:00
maybePreserve ( c , stackBefore , localsBefore , secondSize , second ,
second - > source ) ;
2008-10-15 00:45:31 +00:00
removeSite ( c , second , second - > source ) ;
2008-09-07 20:12:11 +00:00
target = second - > source ;
} else {
target = resultRead - > allocateSite ( c ) ;
2008-10-04 17:26:35 +00:00
addSite ( c , stackBefore , localsBefore , resultSize , result , target ) ;
2008-09-07 20:12:11 +00:00
}
2008-04-29 16:25:20 +00:00
2008-10-04 17:26:35 +00:00
// fprintf(stderr, "combine %p and %p into %p\n", first, second, result);
2008-08-16 17:45:36 +00:00
apply ( c , type , firstSize , first - > source , secondSize , second - > source ,
resultSize , target ) ;
2008-04-19 00:19:45 +00:00
2008-09-25 00:48:32 +00:00
nextRead ( c , this , first ) ;
nextRead ( c , this , second ) ;
2008-09-23 21:18:41 +00:00
2008-10-15 00:45:31 +00:00
if ( c - > arch - > condensedAddressing ( ) and live ( result ) ) {
addSite ( c , 0 , 0 , resultSize , result , target ) ;
2008-09-23 21:18:41 +00:00
}
2008-02-11 17:21:41 +00:00
}
2007-12-23 18:48:22 +00:00
2008-08-28 22:43:35 +00:00
TernaryOperation type ;
2008-08-16 17:45:36 +00:00
unsigned firstSize ;
2008-04-17 02:55:38 +00:00
Value * first ;
2008-08-16 17:45:36 +00:00
unsigned secondSize ;
2008-04-17 02:55:38 +00:00
Value * second ;
2008-08-16 17:45:36 +00:00
unsigned resultSize ;
2008-04-17 22:07:32 +00:00
Value * result ;
2008-09-07 20:12:11 +00:00
Read * resultRead ;
2008-02-11 17:21:41 +00:00
} ;
2007-12-20 16:02:00 +00:00
2008-05-06 21:13:02 +00:00
Value *
value ( Context * c , Site * site = 0 , Site * target = 0 )
{
return new ( c - > zone - > allocate ( sizeof ( Value ) ) ) Value ( site , target ) ;
}
2008-11-01 19:14:13 +00:00
void
2008-11-01 22:16:18 +00:00
removeBuddy ( Context * c , Value * v )
2008-11-01 19:14:13 +00:00
{
if ( v - > buddy ! = v ) {
2008-11-01 22:16:18 +00:00
fprintf ( stderr , " remove buddy %p from " , v ) ;
2008-11-01 19:14:13 +00:00
for ( Value * p = v - > buddy ; p ! = v ; p = p - > buddy ) {
fprintf ( stderr , " %p " , p ) ;
}
fprintf ( stderr , " \n " ) ;
}
if ( v - > buddy ! = v ) {
Value * next = v - > buddy ;
v - > buddy = v ;
Value * p = next ;
while ( p - > buddy ! = v ) p = p - > buddy ;
p - > buddy = next ;
2008-11-01 22:16:18 +00:00
if ( not live ( next ) ) {
clearSites ( c , next ) ;
}
2008-11-01 19:14:13 +00:00
}
}
2008-11-01 22:16:18 +00:00
Site *
copy ( Context * c , Site * s )
{
Site * start = 0 ;
Site * end = 0 ;
for ( ; s ; s = s - > next ) {
Site * n = s - > copy ( c ) ;
if ( end ) {
end - > next = n ;
} else {
start = n ;
}
end = n ;
}
return start ;
}
class Snapshot {
public :
Snapshot ( Context * c , Value * value , Snapshot * next ) :
value ( value ) , buddy ( value - > buddy ) , sites ( copy ( c , value - > sites ) ) , next ( next )
{ }
Value * value ;
Value * buddy ;
Site * sites ;
Snapshot * next ;
} ;
Snapshot *
snapshot ( Context * c , Value * value , Snapshot * next )
{
char buffer [ 256 ] ; toString ( c , value - > sites , buffer , 256 ) ;
fprintf ( stderr , " snapshot %p buddy %p sites %s \n " ,
value , value - > buddy , buffer ) ;
return new ( c - > zone - > allocate ( sizeof ( Snapshot ) ) ) Snapshot ( c , value , next ) ;
}
2008-08-28 22:43:35 +00:00
Stack *
stack ( Context * c , Value * value , unsigned size , unsigned index , Stack * next )
{
return new ( c - > zone - > allocate ( sizeof ( Stack ) ) )
Stack ( index , size , value , next ) ;
}
Stack *
stack ( Context * c , Value * value , unsigned size , Stack * next )
{
return stack
2008-11-01 19:14:13 +00:00
( c , value , size , ( next ? next - > index + next - > sizeInWords : 0 ) , next ) ;
2008-08-28 22:43:35 +00:00
}
2008-02-11 17:21:41 +00:00
void
2008-11-01 19:14:13 +00:00
push ( Context * c , unsigned sizeInBytes , Value * v )
2008-02-11 17:21:41 +00:00
{
2008-11-01 19:14:13 +00:00
assert ( c , ceiling ( sizeInBytes , BytesPerWord ) ) ;
2008-04-28 22:08:31 +00:00
2008-11-01 19:14:13 +00:00
v - > local = true ;
c - > stack = stack ( c , v , ceiling ( sizeInBytes , BytesPerWord ) , c - > stack ) ;
2008-08-28 22:43:35 +00:00
}
2008-04-28 22:08:31 +00:00
2008-08-28 22:43:35 +00:00
Value *
2008-11-01 19:14:13 +00:00
pop ( Context * c , unsigned sizeInBytes UNUSED )
2008-08-28 22:43:35 +00:00
{
2008-09-13 21:09:26 +00:00
Stack * s = c - > stack ;
2008-11-01 19:14:13 +00:00
assert ( c , ceiling ( sizeInBytes , BytesPerWord ) = = s - > sizeInWords ) ;
2008-08-28 22:43:35 +00:00
2008-09-13 21:09:26 +00:00
c - > stack = s - > next ;
2008-11-01 19:14:13 +00:00
s - > value - > local = false ;
2008-08-28 22:43:35 +00:00
return s - > value ;
}
void
appendCombine ( Context * c , TernaryOperation type ,
unsigned firstSize , Value * first ,
unsigned secondSize , Value * second ,
unsigned resultSize , Value * result )
{
bool thunk ;
uint8_t firstTypeMask ;
uint64_t firstRegisterMask ;
uint8_t secondTypeMask ;
uint64_t secondRegisterMask ;
uint8_t resultTypeMask ;
uint64_t resultRegisterMask ;
c - > arch - > plan ( type , firstSize , & firstTypeMask , & firstRegisterMask ,
secondSize , & secondTypeMask , & secondRegisterMask ,
resultSize , & resultTypeMask , & resultRegisterMask ,
& thunk ) ;
2008-05-16 00:35:17 +00:00
2008-08-28 22:43:35 +00:00
if ( thunk ) {
2008-09-13 21:09:26 +00:00
Stack * oldStack = c - > stack ;
2008-05-04 20:55:34 +00:00
2008-08-28 22:43:35 +00:00
: : push ( c , secondSize , second ) ;
: : push ( c , firstSize , first ) ;
2008-04-18 03:47:42 +00:00
2008-09-13 21:09:26 +00:00
Stack * argumentStack = c - > stack ;
c - > stack = oldStack ;
2008-05-04 20:55:34 +00:00
2008-08-28 22:43:35 +00:00
appendCall
( c , value ( c , constantSite ( c , c - > client - > getThunk ( type , resultSize ) ) ) ,
0 , 0 , result , resultSize , argumentStack , 2 , 0 ) ;
2008-05-04 20:55:34 +00:00
} else {
2008-09-07 20:12:11 +00:00
Read * resultRead = read
( c , resultSize , resultTypeMask , resultRegisterMask , AnyFrameIndex ) ;
Read * secondRead ;
if ( c - > arch - > condensedAddressing ( ) ) {
secondRead = resultRead ;
} else {
secondRead = read
( c , secondSize , secondTypeMask , secondRegisterMask , AnyFrameIndex ) ;
}
2008-05-19 04:31:52 +00:00
2008-10-14 00:18:18 +00:00
append
( c , new ( c - > zone - > allocate ( sizeof ( CombineEvent ) ) )
CombineEvent
( c , type ,
firstSize , first ,
secondSize , second ,
resultSize , result ,
read ( c , firstSize , firstTypeMask , firstRegisterMask , AnyFrameIndex ) ,
secondRead ,
resultRead ) ) ;
2008-05-04 20:55:34 +00:00
}
2008-02-11 17:21:41 +00:00
}
2007-12-20 16:02:00 +00:00
2008-02-11 17:21:41 +00:00
class TranslateEvent : public Event {
public :
2008-08-28 22:43:35 +00:00
TranslateEvent ( Context * c , BinaryOperation type , unsigned size , Value * value ,
2008-10-15 00:45:31 +00:00
Value * result , Read * valueRead , Read * resultRead ) :
Event ( c ) , type ( type ) , size ( size ) , value ( value ) , result ( result ) ,
resultRead ( resultRead )
2008-02-17 20:57:40 +00:00
{
2008-10-15 00:45:31 +00:00
addRead ( c , this , value , valueRead ) ;
2008-03-15 20:24:04 +00:00
}
2008-09-15 02:28:42 +00:00
virtual const char * name ( ) {
return " TranslateEvent " ;
}
2008-02-17 20:57:40 +00:00
2008-09-15 02:28:42 +00:00
virtual void compile ( Context * c ) {
2008-10-15 00:45:31 +00:00
Site * target ;
if ( c - > arch - > condensedAddressing ( ) ) {
maybePreserve ( c , stackBefore , localsBefore , size , value , value - > source ) ;
removeSite ( c , value , value - > source ) ;
target = value - > source ;
} else {
target = resultRead - > allocateSite ( c ) ;
addSite ( c , stackBefore , localsBefore , size , result , target ) ;
}
2008-04-29 16:25:20 +00:00
2008-08-28 22:43:35 +00:00
apply ( c , type , size , value - > source , size , target ) ;
2008-04-19 00:19:45 +00:00
2008-09-25 00:48:32 +00:00
nextRead ( c , this , value ) ;
2008-04-19 00:19:45 +00:00
2008-10-15 00:45:31 +00:00
if ( c - > arch - > condensedAddressing ( ) and live ( result ) ) {
addSite ( c , 0 , 0 , size , result , target ) ;
2008-04-21 00:21:48 +00:00
}
2008-02-11 17:21:41 +00:00
}
2007-12-20 16:02:00 +00:00
2008-08-28 22:43:35 +00:00
BinaryOperation type ;
2008-02-12 02:06:12 +00:00
unsigned size ;
2008-04-17 02:55:38 +00:00
Value * value ;
Value * result ;
2008-10-15 00:45:31 +00:00
Read * resultRead ;
2008-02-11 17:21:41 +00:00
} ;
2007-12-12 18:59:45 +00:00
2008-02-11 17:21:41 +00:00
void
2008-08-28 22:43:35 +00:00
appendTranslate ( Context * c , BinaryOperation type , unsigned size , Value * value ,
2008-04-17 02:55:38 +00:00
Value * result )
2008-02-11 17:21:41 +00:00
{
2008-05-31 22:14:27 +00:00
bool thunk ;
2008-08-28 22:43:35 +00:00
uint8_t firstTypeMask ;
uint64_t firstRegisterMask ;
uint8_t resultTypeMask ;
uint64_t resultRegisterMask ;
2008-05-04 20:55:34 +00:00
2008-08-28 22:43:35 +00:00
c - > arch - > plan ( type , size , & firstTypeMask , & firstRegisterMask ,
size , & resultTypeMask , & resultRegisterMask ,
& thunk ) ;
2008-05-04 20:55:34 +00:00
2008-05-31 22:14:27 +00:00
assert ( c , not thunk ) ; // todo
2008-05-04 20:55:34 +00:00
2008-10-15 00:45:31 +00:00
Read * resultRead = read
( c , size , resultTypeMask , resultRegisterMask , AnyFrameIndex ) ;
Read * firstRead ;
if ( c - > arch - > condensedAddressing ( ) ) {
firstRead = resultRead ;
} else {
firstRead = read
( c , size , firstTypeMask , firstRegisterMask , AnyFrameIndex ) ;
}
2008-08-28 22:43:35 +00:00
// todo: respect resultTypeMask and resultRegisterMask
2008-05-19 04:31:52 +00:00
2008-10-14 00:18:18 +00:00
append ( c , new ( c - > zone - > allocate ( sizeof ( TranslateEvent ) ) )
TranslateEvent
2008-10-15 00:45:31 +00:00
( c , type , size , value , result , firstRead , resultRead ) ) ;
2008-02-11 17:21:41 +00:00
}
2007-12-20 16:02:00 +00:00
2008-03-15 23:54:20 +00:00
class MemoryEvent : public Event {
public :
2008-04-17 20:48:26 +00:00
MemoryEvent ( Context * c , Value * base , int displacement , Value * index ,
unsigned scale , Value * result ) :
Event ( c ) , base ( base ) , displacement ( displacement ) , index ( index ) ,
scale ( scale ) , result ( result )
2008-03-15 23:54:20 +00:00
{
2008-09-15 02:28:42 +00:00
addRead ( c , this , base , anyRegisterRead ( c , BytesPerWord ) ) ;
if ( index ) addRead ( c , this , index , registerOrConstantRead ( c , BytesPerWord ) ) ;
}
virtual const char * name ( ) {
return " MemoryEvent " ;
2008-03-15 23:54:20 +00:00
}
2008-04-17 22:07:32 +00:00
virtual void compile ( Context * c ) {
2008-04-17 20:48:26 +00:00
int indexRegister ;
2008-06-10 14:49:13 +00:00
int displacement = this - > displacement ;
unsigned scale = this - > scale ;
2008-04-17 20:48:26 +00:00
if ( index ) {
2008-06-11 00:17:44 +00:00
ConstantSite * constant = findConstantSite ( c , index ) ;
2008-06-10 14:49:13 +00:00
if ( constant ) {
indexRegister = NoRegister ;
displacement + = ( constant - > value . value - > value ( ) * scale ) ;
scale = 1 ;
} else {
assert ( c , index - > source - > type ( c ) = = RegisterOperand ) ;
indexRegister = static_cast < RegisterSite * >
( index - > source ) - > register_ . low ;
}
2008-04-17 20:48:26 +00:00
} else {
indexRegister = NoRegister ;
}
2008-04-18 00:39:41 +00:00
assert ( c , base - > source - > type ( c ) = = RegisterOperand ) ;
int baseRegister = static_cast < RegisterSite * > ( base - > source ) - > register_ . low ;
2008-04-17 20:48:26 +00:00
2008-09-25 00:48:32 +00:00
nextRead ( c , this , base ) ;
2008-04-19 00:19:45 +00:00
if ( index ) {
2008-06-10 14:49:13 +00:00
if ( BytesPerWord = = 8 and indexRegister ! = NoRegister ) {
2008-08-28 22:43:35 +00:00
apply ( c , Move , 4 , index - > source , 8 , index - > source ) ;
2008-05-04 20:55:34 +00:00
}
2008-05-13 17:27:57 +00:00
2008-09-25 00:48:32 +00:00
nextRead ( c , this , index ) ;
2008-04-19 00:19:45 +00:00
}
2008-04-19 21:52:45 +00:00
result - > target = memorySite
( c , baseRegister , displacement , indexRegister , scale ) ;
2008-07-17 23:34:38 +00:00
addSite ( c , 0 , 0 , 0 , result , result - > target ) ;
2008-03-15 23:54:20 +00:00
}
2008-04-17 02:55:38 +00:00
Value * base ;
2008-04-17 20:48:26 +00:00
int displacement ;
2008-04-17 02:55:38 +00:00
Value * index ;
2008-04-17 20:48:26 +00:00
unsigned scale ;
2008-04-17 02:55:38 +00:00
Value * result ;
2008-03-15 23:54:20 +00:00
} ;
void
2008-04-17 20:48:26 +00:00
appendMemory ( Context * c , Value * base , int displacement , Value * index ,
unsigned scale , Value * result )
2008-04-17 02:55:38 +00:00
{
2008-10-14 00:18:18 +00:00
append ( c , new ( c - > zone - > allocate ( sizeof ( MemoryEvent ) ) )
MemoryEvent ( c , base , displacement , index , scale , result ) ) ;
2008-04-17 20:48:26 +00:00
}
2008-04-20 05:23:08 +00:00
class BranchEvent : public Event {
public :
BranchEvent ( Context * c , UnaryOperation type , Value * address ) :
Event ( c ) , type ( type ) , address ( address )
{
2008-09-20 23:42:46 +00:00
address - > addPredecessor ( c , this ) ;
addRead ( c , this , address , read
( c , BytesPerWord , ~ 0 , ~ static_cast < uint64_t > ( 0 ) , AnyFrameIndex ) ) ;
2008-04-20 05:23:08 +00:00
}
2008-09-15 02:28:42 +00:00
virtual const char * name ( ) {
return " BranchEvent " ;
}
2008-04-20 05:23:08 +00:00
2008-09-15 02:28:42 +00:00
virtual void compile ( Context * c ) {
2008-06-11 00:17:44 +00:00
bool jump ;
UnaryOperation type = this - > type ;
if ( type ! = Jump ) {
switch ( c - > constantCompare ) {
case CompareLess :
switch ( type ) {
case JumpIfLess :
case JumpIfLessOrEqual :
case JumpIfNotEqual :
jump = true ;
type = Jump ;
break ;
default :
jump = false ;
}
break ;
case CompareGreater :
switch ( type ) {
case JumpIfGreater :
case JumpIfGreaterOrEqual :
case JumpIfNotEqual :
jump = true ;
type = Jump ;
break ;
default :
jump = false ;
}
break ;
case CompareEqual :
switch ( type ) {
case JumpIfEqual :
case JumpIfLessOrEqual :
case JumpIfGreaterOrEqual :
jump = true ;
type = Jump ;
break ;
default :
jump = false ;
}
break ;
case CompareNone :
jump = true ;
break ;
default : abort ( c ) ;
}
} else {
jump = true ;
}
if ( jump ) {
apply ( c , type , BytesPerWord , address - > source ) ;
}
2008-04-20 05:23:08 +00:00
2008-09-25 00:48:32 +00:00
nextRead ( c , this , address ) ;
2008-04-20 05:23:08 +00:00
}
2008-10-08 00:08:13 +00:00
virtual bool isBranch ( ) { return true ; }
2008-04-20 05:23:08 +00:00
UnaryOperation type ;
Value * address ;
} ;
void
appendBranch ( Context * c , UnaryOperation type , Value * address )
{
2008-10-14 00:18:18 +00:00
append ( c , new ( c - > zone - > allocate ( sizeof ( BranchEvent ) ) )
BranchEvent ( c , type , address ) ) ;
2008-04-18 03:47:42 +00:00
}
2008-05-31 22:14:27 +00:00
class BoundsCheckEvent : public Event {
public :
BoundsCheckEvent ( Context * c , Value * object , unsigned lengthOffset ,
Value * index , intptr_t handler ) :
Event ( c ) , object ( object ) , lengthOffset ( lengthOffset ) , index ( index ) ,
handler ( handler )
{
2008-09-15 02:28:42 +00:00
addRead ( c , this , object , anyRegisterRead ( c , BytesPerWord ) ) ;
addRead ( c , this , index , registerOrConstantRead ( c , BytesPerWord ) ) ;
2008-05-31 22:14:27 +00:00
}
2008-09-15 02:28:42 +00:00
virtual const char * name ( ) {
return " BoundsCheckEvent " ;
}
2008-05-31 22:14:27 +00:00
2008-09-15 02:28:42 +00:00
virtual void compile ( Context * c ) {
2008-05-31 22:14:27 +00:00
Assembler * a = c - > assembler ;
2008-06-11 00:17:44 +00:00
ConstantSite * constant = findConstantSite ( c , index ) ;
2008-08-30 20:12:27 +00:00
CodePromise * nextPromise = codePromise
2008-09-09 00:31:19 +00:00
( c , static_cast < Promise * > ( 0 ) ) ;
2008-05-31 23:06:45 +00:00
CodePromise * outOfBoundsPromise = 0 ;
2008-05-31 22:14:27 +00:00
if ( constant ) {
expect ( c , constant - > value . value - > value ( ) > = 0 ) ;
} else {
2008-09-09 00:31:19 +00:00
outOfBoundsPromise = codePromise ( c , static_cast < Promise * > ( 0 ) ) ;
2008-05-31 22:14:27 +00:00
2008-08-30 20:12:27 +00:00
apply ( c , Compare , 4 , constantSite ( c , resolved ( c , 0 ) ) , 4 , index - > source ) ;
2008-05-31 22:14:27 +00:00
Assembler : : Constant outOfBoundsConstant ( outOfBoundsPromise ) ;
a - > apply
( JumpIfLess , BytesPerWord , ConstantOperand , & outOfBoundsConstant ) ;
}
assert ( c , object - > source - > type ( c ) = = RegisterOperand ) ;
int base = static_cast < RegisterSite * > ( object - > source ) - > register_ . low ;
Site * length = memorySite ( c , base , lengthOffset ) ;
2008-08-30 20:12:27 +00:00
length - > acquire ( c , 0 , 0 , 0 , 0 ) ;
2008-05-31 22:14:27 +00:00
2008-08-30 20:12:27 +00:00
apply ( c , Compare , 4 , index - > source , 4 , length ) ;
2008-05-31 22:14:27 +00:00
length - > release ( c ) ;
Assembler : : Constant nextConstant ( nextPromise ) ;
a - > apply ( JumpIfGreater , BytesPerWord , ConstantOperand , & nextConstant ) ;
if ( constant = = 0 ) {
2008-08-30 20:12:27 +00:00
outOfBoundsPromise - > offset = a - > offset ( ) ;
2008-05-31 22:14:27 +00:00
}
2008-05-31 22:53:37 +00:00
Assembler : : Constant handlerConstant ( resolved ( c , handler ) ) ;
2008-05-31 22:14:27 +00:00
a - > apply ( Call , BytesPerWord , ConstantOperand , & handlerConstant ) ;
2008-08-30 20:12:27 +00:00
nextPromise - > offset = a - > offset ( ) ;
2008-05-31 22:14:27 +00:00
2008-09-25 00:48:32 +00:00
nextRead ( c , this , object ) ;
nextRead ( c , this , index ) ;
2008-05-31 22:14:27 +00:00
}
Value * object ;
unsigned lengthOffset ;
Value * index ;
intptr_t handler ;
} ;
void
appendBoundsCheck ( Context * c , Value * object , unsigned lengthOffset ,
Value * index , intptr_t handler )
{
2008-10-14 00:18:18 +00:00
append ( c , new ( c - > zone - > allocate ( sizeof ( BoundsCheckEvent ) ) )
BoundsCheckEvent ( c , object , lengthOffset , index , handler ) ) ;
2008-05-31 22:14:27 +00:00
}
2008-09-25 00:48:32 +00:00
class FrameSiteEvent : public Event {
2008-09-09 00:31:19 +00:00
public :
2008-09-25 00:48:32 +00:00
FrameSiteEvent ( Context * c , Value * value , unsigned size , int index ) :
2008-09-09 00:31:19 +00:00
Event ( c ) , value ( value ) , size ( size ) , index ( index )
{ }
2008-09-15 02:28:42 +00:00
virtual const char * name ( ) {
2008-09-25 00:48:32 +00:00
return " FrameSiteEvent " ;
2008-09-15 02:28:42 +00:00
}
2008-09-09 00:31:19 +00:00
2008-09-15 02:28:42 +00:00
virtual void compile ( Context * c ) {
2008-10-04 17:26:35 +00:00
addSite ( c , stackBefore , localsBefore , size , value , frameSite ( c , index ) ) ;
2008-09-09 00:31:19 +00:00
}
Value * value ;
unsigned size ;
int index ;
} ;
void
2008-09-25 00:48:32 +00:00
appendFrameSite ( Context * c , Value * value , unsigned size , int index )
2008-09-09 00:31:19 +00:00
{
2008-10-14 00:18:18 +00:00
append ( c , new ( c - > zone - > allocate ( sizeof ( FrameSiteEvent ) ) )
FrameSiteEvent ( c , value , size , index ) ) ;
2008-09-09 00:31:19 +00:00
}
2008-10-05 00:14:43 +00:00
unsigned
frameFootprint ( Context * c , Stack * s )
{
2008-11-01 19:14:13 +00:00
return c - > localFootprint + ( s ? ( s - > index + s - > sizeInWords ) : 0 ) ;
2008-10-14 00:18:18 +00:00
}
void
2008-10-15 00:45:31 +00:00
visit ( Context * c , Link * link )
2008-10-14 00:18:18 +00:00
{
2008-10-17 00:10:35 +00:00
// fprintf(stderr, "visit link from %d to %d\n",
// link->predecessor->logicalInstruction->index,
// link->successor->logicalInstruction->index);
2008-10-14 00:18:18 +00:00
ForkState * forkState = link - > forkState ;
if ( forkState ) {
for ( unsigned i = 0 ; i < forkState - > readCount ; + + i ) {
MultiReadPair * p = forkState - > reads + i ;
Value * v = p - > value ;
v - > reads = p - > read - > nextTarget ( ) ;
2008-10-17 00:10:35 +00:00
// fprintf(stderr, "next read %p for %p\n", v->reads, v);
2008-10-14 00:18:18 +00:00
if ( not live ( v ) ) {
clearSites ( c , v ) ;
}
}
}
JunctionState * junctionState = link - > junctionState ;
if ( junctionState ) {
for ( unsigned i = 0 ; i < junctionState - > readCount ; + + i ) {
assert ( c , junctionState - > reads [ i ] . value - > reads
= = junctionState - > reads [ i ] . read ) ;
nextRead ( c , 0 , junctionState - > reads [ i ] . value ) ;
}
}
}
2008-11-01 19:14:13 +00:00
class BuddyEvent : public Event {
public :
BuddyEvent ( Context * c , Value * original , Value * buddy , unsigned size ) :
Event ( c ) , original ( original ) , buddy ( buddy )
{
addRead ( c , this , original ,
read ( c , size , ~ 0 , ~ static_cast < uint64_t > ( 0 ) , AnyFrameIndex ) ) ;
}
virtual const char * name ( ) {
return " BuddyEvent " ;
}
virtual void compile ( Context * c ) {
buddy - > buddy = original ;
Value * p = original ;
while ( p - > buddy ! = original ) p = p - > buddy ;
p - > buddy = buddy ;
2008-11-01 22:16:18 +00:00
fprintf ( stderr , " add buddy %p to " , buddy ) ;
for ( Value * p = buddy - > buddy ; p ! = buddy ; p = p - > buddy ) {
2008-11-01 19:14:13 +00:00
fprintf ( stderr , " %p " , p ) ;
}
fprintf ( stderr , " \n " ) ;
nextRead ( c , this , original ) ;
}
Value * original ;
Value * buddy ;
} ;
void
appendBuddy ( Context * c , Value * original , Value * buddy , unsigned size )
{
append ( c , new ( c - > zone - > allocate ( sizeof ( BuddyEvent ) ) )
BuddyEvent ( c , original , buddy , size ) ) ;
}
2008-09-13 21:09:26 +00:00
class DummyEvent : public Event {
public :
DummyEvent ( Context * c ) :
Event ( c )
2008-10-05 00:14:43 +00:00
{ }
2008-09-15 02:28:42 +00:00
virtual const char * name ( ) {
return " DummyEvent " ;
}
2008-09-13 21:09:26 +00:00
virtual void compile ( Context * ) { }
} ;
void
appendDummy ( Context * c )
{
2008-10-05 00:14:43 +00:00
Stack * stack = c - > stack ;
Local * locals = c - > locals ;
LogicalInstruction * i = c - > logicalCode [ c - > logicalIp ] ;
c - > stack = i - > stack ;
c - > locals = i - > locals ;
2008-10-14 00:18:18 +00:00
append ( c , new ( c - > zone - > allocate ( sizeof ( DummyEvent ) ) ) DummyEvent ( c ) ) ;
2008-10-05 00:14:43 +00:00
c - > stack = stack ;
c - > locals = locals ;
2008-09-13 21:09:26 +00:00
}
2008-10-14 00:18:18 +00:00
void
append ( Context * c , Event * e )
{
2008-10-25 02:12:02 +00:00
assert ( c , c - > logicalIp > = 0 ) ;
LogicalInstruction * i = c - > logicalCode [ c - > logicalIp ] ;
if ( c - > stack ! = i - > stack or c - > locals ! = i - > locals ) {
appendDummy ( c ) ;
2008-10-14 00:18:18 +00:00
}
2008-10-25 02:12:02 +00:00
if ( DebugAppend ) {
fprintf ( stderr , " -- append %s at %d with %d stack before \n " ,
e - > name ( ) , e - > logicalInstruction - > index , c - > stack ?
2008-11-01 19:14:13 +00:00
c - > stack - > index + c - > stack - > sizeInWords : 0 ) ;
2008-10-25 02:12:02 +00:00
}
2008-10-14 00:18:18 +00:00
if ( c - > lastEvent ) {
c - > lastEvent - > next = e ;
} else {
c - > firstEvent = e ;
}
c - > lastEvent = e ;
Event * p = c - > predecessor ;
if ( p ) {
Link * link = : : link ( c , p , e - > predecessors , e , p - > successors , c - > forkState ) ;
e - > predecessors = link ;
p - > successors = link ;
}
c - > forkState = 0 ;
c - > predecessor = e ;
if ( e - > logicalInstruction - > firstEvent = = 0 ) {
e - > logicalInstruction - > firstEvent = e ;
}
e - > logicalInstruction - > lastEvent = e ;
}
2008-04-18 03:47:42 +00:00
Site *
2008-09-24 00:01:42 +00:00
readSource ( Context * c , Stack * stack , Local * locals , Read * r )
2008-04-18 03:47:42 +00:00
{
2008-11-01 19:14:13 +00:00
fprintf ( stderr , " read source for %p \n " , r - > value ) ;
2008-05-15 20:00:57 +00:00
2008-08-30 20:12:27 +00:00
Site * site = r - > pickSite ( c , r - > value ) ;
2008-04-18 03:47:42 +00:00
2008-08-30 20:12:27 +00:00
if ( site ) {
2008-04-18 00:39:41 +00:00
return site ;
2008-08-30 20:12:27 +00:00
} else {
Site * target = r - > allocateSite ( c ) ;
unsigned copyCost ;
2008-11-01 19:14:13 +00:00
site = pick ( c , r - > value , target , & copyCost ) ;
2008-08-30 20:12:27 +00:00
assert ( c , copyCost ) ;
2008-10-04 17:26:35 +00:00
move ( c , stack , locals , r - > size , r - > value , site , target ) ;
2008-08-30 20:12:27 +00:00
return target ;
2008-04-17 02:55:38 +00:00
}
2007-12-11 21:26:59 +00:00
}
2008-07-23 23:58:29 +00:00
Site *
2008-10-25 02:12:02 +00:00
pickJunctionSite ( Context * c , Value * v , Read * r , unsigned frameIndex )
2008-07-23 23:58:29 +00:00
{
2008-09-27 22:01:39 +00:00
if ( c - > availableRegisterCount > 1 ) {
2008-11-01 19:14:13 +00:00
Site * s = r - > pickSite ( c , v ) ;
2008-10-12 00:23:08 +00:00
2008-11-01 19:14:13 +00:00
if ( s = = 0 ) {
s = pick ( c , v ) ;
}
2008-10-04 17:26:35 +00:00
2008-11-01 19:14:13 +00:00
if ( s and s - > match
( c , ( 1 < < MemoryOperand ) | ( 1 < < RegisterOperand ) ,
~ 0 , AnyFrameIndex ) )
{
return s ;
2008-10-06 00:50:59 +00:00
}
2008-10-04 17:26:35 +00:00
2008-11-01 19:14:13 +00:00
s = r - > allocateSite ( c ) ;
if ( s ) return s ;
2008-09-27 22:01:39 +00:00
return freeRegisterSite ( c ) ;
} else {
2008-10-25 02:12:02 +00:00
return frameSite ( c , frameIndex ) ;
2008-09-27 22:01:39 +00:00
}
2008-07-23 23:58:29 +00:00
}
unsigned
2008-10-25 02:12:02 +00:00
resolveJunctionSite ( Context * c , Event * e , Value * v ,
unsigned siteIndex , unsigned frameIndex ,
2008-10-04 17:26:35 +00:00
Site * * frozenSites , unsigned frozenSiteIndex )
2008-07-23 23:58:29 +00:00
{
2008-10-25 02:12:02 +00:00
assert ( c , siteIndex < frameFootprint ( c , e - > stackAfter ) ) ;
2008-09-15 02:28:42 +00:00
2008-07-23 23:58:29 +00:00
if ( live ( v ) ) {
2008-11-01 22:16:18 +00:00
assert ( c , hasSite ( v ) ) ;
2008-09-25 00:48:32 +00:00
2008-08-30 20:12:27 +00:00
Read * r = v - > reads ;
2008-10-25 02:12:02 +00:00
Site * original = e - > junctionSites [ siteIndex ] ;
2008-10-12 00:23:08 +00:00
Site * target ;
2008-07-23 23:58:29 +00:00
2008-10-12 00:23:08 +00:00
if ( original ) {
target = original ;
} else {
2008-10-25 02:12:02 +00:00
target = pickJunctionSite ( c , v , r , frameIndex ) ;
2008-07-23 23:58:29 +00:00
}
unsigned copyCost ;
2008-11-01 19:14:13 +00:00
Site * site = pick ( c , v , target , & copyCost ) ;
2008-11-01 22:16:18 +00:00
2008-11-01 19:14:13 +00:00
if ( copyCost ) {
2008-10-04 17:26:35 +00:00
move ( c , e - > stackAfter , e - > localsAfter , r - > size , v , site , target ) ;
2008-09-25 00:48:32 +00:00
} else {
target = site ;
2008-07-23 23:58:29 +00:00
}
if ( original = = 0 ) {
frozenSites [ frozenSiteIndex + + ] = target ;
target - > freeze ( c ) ;
2008-10-25 02:12:02 +00:00
e - > junctionSites [ siteIndex ] = target - > copy ( c ) ;
2008-07-23 23:58:29 +00:00
}
2008-10-12 00:23:08 +00:00
char buffer [ 256 ] ; target - > toString ( c , buffer , 256 ) ;
2008-10-25 02:12:02 +00:00
fprintf ( stderr , " resolved junction site %d %s %p \n " , frameIndex , buffer , v ) ;
2008-07-23 23:58:29 +00:00
}
return frozenSiteIndex ;
}
void
propagateJunctionSites ( Context * c , Event * e , Site * * sites )
{
2008-10-14 00:18:18 +00:00
for ( Link * pl = e - > predecessors ; pl ; pl = pl - > nextPredecessor ) {
Event * p = pl - > predecessor ;
2008-07-23 23:58:29 +00:00
if ( p - > junctionSites = = 0 ) {
p - > junctionSites = sites ;
2008-10-14 00:18:18 +00:00
for ( Link * sl = p - > successors ; sl ; sl = sl - > nextSuccessor ) {
Event * s = sl - > successor ;
2008-08-30 20:12:27 +00:00
propagateJunctionSites ( c , s , sites ) ;
2008-07-23 23:58:29 +00:00
}
}
}
}
2008-08-16 17:45:36 +00:00
void
populateSiteTables ( Context * c , Event * e )
{
2008-10-04 17:26:35 +00:00
unsigned frameFootprint = : : frameFootprint ( c , e - > stackAfter ) ;
2008-04-17 02:55:38 +00:00
2008-08-30 20:12:27 +00:00
{ Site * frozenSites [ frameFootprint ] ;
2008-08-16 17:45:36 +00:00
unsigned frozenSiteIndex = 0 ;
2008-04-17 02:55:38 +00:00
2008-08-16 17:45:36 +00:00
if ( e - > junctionSites ) {
2008-11-01 19:14:13 +00:00
for ( FrameIterator it ( c , e - > stackAfter , e - > localsAfter ) ; it . hasMore ( ) ; ) {
FrameIterator : : Element el = it . next ( c ) ;
if ( e - > junctionSites [ el . localIndex ] ) {
2008-10-04 17:26:35 +00:00
frozenSiteIndex = resolveJunctionSite
2008-11-01 19:14:13 +00:00
( c , e , el . value , el . localIndex , frameIndex ( c , & el ) , frozenSites ,
frozenSiteIndex ) ;
2008-08-16 17:45:36 +00:00
}
}
} else {
2008-10-14 00:18:18 +00:00
for ( Link * sl = e - > successors ; sl ; sl = sl - > nextSuccessor ) {
Event * s = sl - > successor ;
if ( s - > predecessors - > nextPredecessor ) {
2008-08-30 20:12:27 +00:00
unsigned size = sizeof ( Site * ) * frameFootprint ;
2008-08-16 17:45:36 +00:00
Site * * junctionSites = static_cast < Site * * >
( c - > zone - > allocate ( size ) ) ;
memset ( junctionSites , 0 , size ) ;
2008-04-17 02:55:38 +00:00
2008-08-16 17:45:36 +00:00
propagateJunctionSites ( c , s , junctionSites ) ;
break ;
2008-04-20 05:23:08 +00:00
}
2008-07-23 23:58:29 +00:00
}
2008-08-16 17:45:36 +00:00
}
2008-07-23 23:58:29 +00:00
2008-08-16 17:45:36 +00:00
if ( e - > junctionSites ) {
2008-11-01 19:14:13 +00:00
for ( FrameIterator it ( c , e - > stackAfter , e - > localsAfter ) ; it . hasMore ( ) ; ) {
FrameIterator : : Element el = it . next ( c ) ;
if ( e - > junctionSites [ el . localIndex ] = = 0 ) {
2008-09-15 02:28:42 +00:00
frozenSiteIndex = resolveJunctionSite
2008-11-01 19:14:13 +00:00
( c , e , el . value , el . localIndex , frameIndex ( c , & el ) , frozenSites ,
frozenSiteIndex ) ;
2008-10-06 00:50:59 +00:00
}
}
2008-10-25 02:12:02 +00:00
fprintf ( stderr , " resolved junction sites %p at %d \n " ,
e - > junctionSites , e - > logicalInstruction - > index ) ;
2008-07-23 23:58:29 +00:00
}
2008-08-16 17:45:36 +00:00
while ( frozenSiteIndex ) {
frozenSites [ - - frozenSiteIndex ] - > thaw ( c ) ;
}
}
2008-07-23 23:58:29 +00:00
2008-10-14 00:18:18 +00:00
if ( e - > successors - > nextSuccessor ) {
2008-11-01 19:14:13 +00:00
for ( FrameIterator it ( c , e - > stackAfter , e - > localsAfter ) ; it . hasMore ( ) ; ) {
FrameIterator : : Element el = it . next ( c ) ;
2008-11-01 22:16:18 +00:00
e - > snapshots = snapshot ( c , el . value , e - > snapshots ) ;
for ( Value * p = el . value - > buddy ; p ! = el . value ; p = p - > buddy ) {
e - > snapshots = snapshot ( c , p , e - > snapshots ) ;
}
2008-08-16 17:45:36 +00:00
}
2008-09-15 02:28:42 +00:00
2008-11-01 22:16:18 +00:00
fprintf ( stderr , " captured snapshots %p at %d \n " ,
e - > snapshots , e - > logicalInstruction - > index ) ;
}
2008-10-25 02:12:02 +00:00
2008-11-01 22:16:18 +00:00
if ( e - > junctionSites ) {
for ( FrameIterator it ( c , e - > stackAfter , e - > localsAfter ) ; it . hasMore ( ) ; ) {
FrameIterator : : Element el = it . next ( c ) ;
removeBuddy ( c , el . value ) ;
}
2008-08-16 17:45:36 +00:00
}
}
2008-04-17 02:55:38 +00:00
2008-10-12 00:23:08 +00:00
void
2008-11-01 22:16:18 +00:00
setSites ( Context * c , Event * e , Value * v , Site * s , unsigned size )
2008-10-12 00:23:08 +00:00
{
for ( ; s ; s = s - > next ) {
2008-11-01 22:16:18 +00:00
addSite ( c , e - > stackBefore , e - > localsBefore , size , v , s - > copy ( c ) ) ;
2008-10-12 00:23:08 +00:00
}
char buffer [ 256 ] ; toString ( c , v - > sites , buffer , 256 ) ;
2008-11-01 22:16:18 +00:00
fprintf ( stderr , " set sites %s for %p \n " , buffer , v ) ;
2008-10-12 00:23:08 +00:00
}
2008-08-16 17:45:36 +00:00
void
2008-11-01 22:16:18 +00:00
resetFrame ( Context * c , Event * e )
2008-08-16 17:45:36 +00:00
{
2008-11-01 19:14:13 +00:00
for ( FrameIterator it ( c , e - > stackBefore , e - > localsBefore ) ; it . hasMore ( ) ; ) {
FrameIterator : : Element el = it . next ( c ) ;
clearSites ( c , el . value ) ;
2008-10-12 00:23:08 +00:00
}
2008-11-01 22:16:18 +00:00
}
void
setSites ( Context * c , Event * e , Site * * sites )
{
resetFrame ( c , e ) ;
2008-10-12 00:23:08 +00:00
2008-11-01 19:14:13 +00:00
for ( FrameIterator it ( c , e - > stackBefore , e - > localsBefore ) ; it . hasMore ( ) ; ) {
FrameIterator : : Element el = it . next ( c ) ;
2008-11-01 22:16:18 +00:00
if ( sites [ el . localIndex ] ) {
Read * r = live ( el . value ) ;
if ( r ) {
setSites ( c , e , el . value , sites [ el . localIndex ] , r - > size ) ;
}
}
}
}
void
restore ( Context * c , Event * e , Snapshot * snapshots )
{
for ( Snapshot * s = snapshots ; s ; s = s - > next ) {
char buffer [ 256 ] ; toString ( c , s - > sites , buffer , 256 ) ;
fprintf ( stderr , " restore %p buddy %p sites %s \n " ,
s - > value , s - > value - > buddy , buffer ) ;
s - > value - > buddy = s - > buddy ;
}
resetFrame ( c , e ) ;
for ( Snapshot * s = snapshots ; s ; s = s - > next ) {
if ( live ( s - > value ) ) {
Read * r = live ( s - > value ) ;
if ( r and s - > sites ) {
setSites ( c , e , s - > value , s - > sites , r - > size ) ;
}
2008-10-12 00:23:08 +00:00
}
}
2008-08-16 17:45:36 +00:00
}
2008-07-23 23:58:29 +00:00
2008-08-16 17:45:36 +00:00
void
populateSources ( Context * c , Event * e )
{
Site * frozenSites [ e - > readCount ] ;
unsigned frozenSiteIndex = 0 ;
for ( Read * r = e - > reads ; r ; r = r - > eventNext ) {
2008-10-04 17:26:35 +00:00
r - > value - > source = readSource ( c , e - > stackBefore , e - > localsBefore , r ) ;
2008-08-16 17:45:36 +00:00
if ( r - > value - > source ) {
assert ( c , frozenSiteIndex < e - > readCount ) ;
frozenSites [ frozenSiteIndex + + ] = r - > value - > source ;
r - > value - > source - > freeze ( c ) ;
2008-07-23 23:58:29 +00:00
}
2008-08-16 17:45:36 +00:00
}
while ( frozenSiteIndex ) {
frozenSites [ - - frozenSiteIndex ] - > thaw ( c ) ;
}
}
2008-07-23 23:58:29 +00:00
2008-09-22 00:58:54 +00:00
void
2008-10-14 00:18:18 +00:00
addStubRead ( Context * c , Value * v , unsigned size , JunctionState * state ,
unsigned * count )
2008-09-22 00:58:54 +00:00
{
2008-11-01 19:14:13 +00:00
if ( v ) {
2008-10-14 00:18:18 +00:00
StubRead * r = stubRead ( c , size ) ;
fprintf ( stderr , " add stub read %p to %p \n " , r , v ) ;
addRead ( c , 0 , v , r ) ;
2008-09-22 00:58:54 +00:00
2008-10-14 00:18:18 +00:00
StubReadPair * p = state - > reads + ( ( * count ) + + ) ;
2008-09-22 00:58:54 +00:00
p - > value = v ;
p - > read = r ;
}
}
void
2008-10-14 00:18:18 +00:00
populateJunctionReads ( Context * c , Link * link )
2008-09-22 00:58:54 +00:00
{
2008-10-14 00:18:18 +00:00
JunctionState * state = new
( c - > zone - > allocate
( sizeof ( JunctionState )
+ ( sizeof ( StubReadPair ) * frameFootprint ( c , c - > stack ) ) ) )
JunctionState ;
2008-09-22 14:28:18 +00:00
2008-10-14 00:18:18 +00:00
link - > junctionState = state ;
unsigned count = 0 ;
2008-11-01 19:14:13 +00:00
for ( FrameIterator it ( c , c - > stack , c - > locals ) ; it . hasMore ( ) ; ) {
FrameIterator : : Element e = it . next ( c ) ;
addStubRead ( c , e . value , e . sizeInBytes , state , & count ) ;
2008-09-22 00:58:54 +00:00
}
2008-10-14 00:18:18 +00:00
state - > readCount = count ;
2008-09-22 00:58:54 +00:00
}
void
2008-10-14 00:18:18 +00:00
updateJunctionReads ( Context * , JunctionState * state )
2008-09-22 00:58:54 +00:00
{
2008-10-14 00:18:18 +00:00
for ( unsigned i = 0 ; i < state - > readCount ; + + i ) {
StubReadPair * p = state - > reads + i ;
if ( p - > read - > read = = 0 ) p - > read - > read = p - > value - > reads ;
2008-09-22 00:58:54 +00:00
}
}
2008-08-16 17:45:36 +00:00
LogicalInstruction *
next ( Context * c , LogicalInstruction * i )
{
for ( unsigned n = i - > index + 1 ; n < c - > logicalCodeLength ; + + n ) {
i = c - > logicalCode [ n ] ;
2008-09-13 21:09:26 +00:00
if ( i ) return i ;
2008-08-16 17:45:36 +00:00
}
return 0 ;
}
2008-07-23 23:58:29 +00:00
2008-08-16 17:45:36 +00:00
class Block {
public :
Block ( Event * head ) :
2008-09-07 20:12:11 +00:00
head ( head ) , nextInstruction ( 0 ) , assemblerBlock ( 0 ) , start ( 0 )
2008-08-16 17:45:36 +00:00
{ }
2008-07-23 23:58:29 +00:00
2008-08-16 17:45:36 +00:00
Event * head ;
LogicalInstruction * nextInstruction ;
2008-09-07 20:12:11 +00:00
Assembler : : Block * assemblerBlock ;
2008-08-16 17:45:36 +00:00
unsigned start ;
} ;
2008-07-23 23:58:29 +00:00
2008-08-16 17:45:36 +00:00
Block *
block ( Context * c , Event * head )
{
return new ( c - > zone - > allocate ( sizeof ( Block ) ) ) Block ( head ) ;
}
unsigned
compile ( Context * c )
{
2008-10-05 00:14:43 +00:00
if ( c - > logicalIp > = 0 and c - > logicalCode [ c - > logicalIp ] - > lastEvent = = 0 ) {
appendDummy ( c ) ;
}
2008-08-16 17:45:36 +00:00
Assembler * a = c - > assembler ;
c - > pass = CompilePass ;
Block * firstBlock = block ( c , c - > firstEvent ) ;
Block * block = firstBlock ;
2008-09-28 19:00:52 +00:00
a - > allocateFrame ( c - > alignedFrameSize ) ;
2008-08-16 17:45:36 +00:00
for ( Event * e = c - > firstEvent ; e ; e = e - > next ) {
2008-09-15 02:28:42 +00:00
if ( DebugCompile ) {
fprintf ( stderr ,
2008-10-12 00:23:08 +00:00
" -- compile %s at %d with %d preds %d succs %d stack before "
2008-10-06 00:50:59 +00:00
" %d after \n " ,
2008-09-15 02:28:42 +00:00
e - > name ( ) , e - > logicalInstruction - > index ,
2008-10-14 00:18:18 +00:00
countPredecessors ( e - > predecessors ) ,
countSuccessors ( e - > successors ) ,
2008-10-04 17:26:35 +00:00
e - > stackBefore ?
2008-11-01 19:14:13 +00:00
e - > stackBefore - > index + e - > stackBefore - > sizeInWords : 0 ,
2008-10-06 00:50:59 +00:00
e - > stackAfter ?
2008-11-01 19:14:13 +00:00
e - > stackAfter - > index + e - > stackAfter - > sizeInWords : 0 ) ;
2008-09-15 02:28:42 +00:00
}
2008-10-15 00:45:31 +00:00
e - > block = block ;
c - > stack = e - > stackBefore ;
c - > locals = e - > localsBefore ;
2008-09-07 01:37:12 +00:00
if ( e - > logicalInstruction - > machineOffset = = 0 ) {
e - > logicalInstruction - > machineOffset = a - > offset ( ) ;
}
2008-09-07 20:12:11 +00:00
if ( e - > predecessors ) {
2008-10-15 00:45:31 +00:00
visit ( c , lastPredecessor ( e - > predecessors ) ) ;
2008-10-14 00:18:18 +00:00
Event * first = e - > predecessors - > predecessor ;
if ( e - > predecessors - > nextPredecessor ) {
for ( Link * pl = e - > predecessors ;
pl - > nextPredecessor ;
pl = pl - > nextPredecessor )
{
updateJunctionReads ( c , pl - > junctionState ) ;
2008-09-22 00:58:54 +00:00
}
2008-10-25 02:12:02 +00:00
fprintf ( stderr , " set sites to junction sites %p at %d \n " ,
first - > junctionSites , first - > logicalInstruction - > index ) ;
2008-10-14 00:18:18 +00:00
setSites ( c , e , first - > junctionSites ) ;
} else if ( first - > successors - > nextSuccessor ) {
2008-11-01 22:16:18 +00:00
fprintf ( stderr , " restore snapshots %p at %d \n " ,
first - > snapshots , first - > logicalInstruction - > index ) ;
restore ( c , e , first - > snapshots ) ;
2008-09-07 20:12:11 +00:00
}
2008-08-16 17:45:36 +00:00
}
populateSources ( c , e ) ;
2008-10-08 00:08:13 +00:00
bool branch = e - > isBranch ( ) ;
if ( branch and e - > successors ) {
populateSiteTables ( c , e ) ;
}
2008-08-16 17:45:36 +00:00
e - > compile ( c ) ;
2008-10-08 00:08:13 +00:00
if ( ( not branch ) and e - > successors ) {
2008-08-16 17:45:36 +00:00
populateSiteTables ( c , e ) ;
2008-07-23 23:58:29 +00:00
}
2008-10-15 00:45:31 +00:00
if ( e - > visitLinks ) {
for ( Cell * cell = reverseDestroy ( e - > visitLinks ) ; cell ; cell = cell - > next )
{
visit ( c , static_cast < Link * > ( cell - > value ) ) ;
}
e - > visitLinks = 0 ;
2008-10-14 00:18:18 +00:00
}
2008-08-16 17:45:36 +00:00
2008-07-23 23:58:29 +00:00
for ( CodePromise * p = e - > promises ; p ; p = p - > next ) {
p - > offset = a - > offset ( ) ;
2008-04-17 02:55:38 +00:00
}
2008-09-20 23:42:46 +00:00
2008-09-22 00:58:54 +00:00
LogicalInstruction * nextInstruction = next ( c , e - > logicalInstruction ) ;
if ( e - > next = = 0
or ( e - > next - > logicalInstruction ! = e - > logicalInstruction
and ( e - > logicalInstruction - > lastEvent = = e
or e - > next - > logicalInstruction ! = nextInstruction ) ) )
{
2008-09-20 23:42:46 +00:00
block - > nextInstruction = nextInstruction ;
block - > assemblerBlock = a - > endBlock ( e - > next ! = 0 ) ;
if ( e - > next ) {
block = : : block ( c , e - > next ) ;
2008-08-16 17:45:36 +00:00
}
}
2008-04-17 02:55:38 +00:00
}
2008-08-16 17:45:36 +00:00
block = firstBlock ;
while ( block - > nextInstruction ) {
Block * next = block - > nextInstruction - > firstEvent - > block ;
2008-09-07 20:12:11 +00:00
next - > start = block - > assemblerBlock - > resolve
( block - > start , next - > assemblerBlock ) ;
2008-08-16 17:45:36 +00:00
block = next ;
}
2008-09-07 20:12:11 +00:00
return block - > assemblerBlock - > resolve ( block - > start , 0 ) ;
2007-12-12 00:27:04 +00:00
}
2008-03-15 20:24:04 +00:00
unsigned
count ( Stack * s )
{
unsigned c = 0 ;
while ( s ) {
+ + c ;
s = s - > next ;
}
return c ;
}
2008-09-15 02:28:42 +00:00
void
2008-10-14 00:18:18 +00:00
allocateTargets ( Context * c , ForkState * state )
2008-09-15 02:28:42 +00:00
{
2008-09-20 23:42:46 +00:00
for ( unsigned i = 0 ; i < state - > readCount ; + + i ) {
2008-09-22 14:28:18 +00:00
MultiReadPair * p = state - > reads + i ;
2008-09-20 23:42:46 +00:00
p - > value - > lastRead = p - > read ;
p - > read - > allocateTarget ( c ) ;
2008-09-15 02:28:42 +00:00
}
}
2008-09-22 00:58:54 +00:00
void
2008-10-14 00:18:18 +00:00
addMultiRead ( Context * c , Value * v , unsigned size , ForkState * state ,
2008-09-24 00:01:42 +00:00
unsigned * count )
2008-09-22 00:58:54 +00:00
{
2008-11-01 19:14:13 +00:00
if ( v ) {
2008-09-24 00:01:42 +00:00
MultiRead * r = multiRead ( c , size ) ;
2008-10-14 00:18:18 +00:00
fprintf ( stderr , " add multi read %p to %p \n " , r , v ) ;
2008-09-22 00:58:54 +00:00
addRead ( c , 0 , v , r ) ;
MultiReadPair * p = state - > reads + ( ( * count ) + + ) ;
p - > value = v ;
p - > read = r ;
}
}
2008-10-14 00:18:18 +00:00
ForkState *
2008-09-13 21:09:26 +00:00
saveState ( Context * c )
2007-12-14 18:27:56 +00:00
{
2008-10-14 00:18:18 +00:00
ForkState * state = new
2008-09-22 14:28:18 +00:00
( c - > zone - > allocate
2008-10-14 00:18:18 +00:00
( sizeof ( ForkState )
+ ( sizeof ( MultiReadPair ) * frameFootprint ( c , c - > stack ) ) ) )
ForkState ( c - > stack , c - > locals , c - > predecessor , c - > logicalIp ) ;
2007-12-14 18:27:56 +00:00
2008-09-20 23:42:46 +00:00
if ( c - > predecessor ) {
2008-10-14 00:18:18 +00:00
c - > forkState = state ;
2008-09-15 02:28:42 +00:00
2008-09-20 23:42:46 +00:00
unsigned count = 0 ;
2008-09-15 02:28:42 +00:00
2008-11-01 19:14:13 +00:00
for ( FrameIterator it ( c , c - > stack , c - > locals ) ; it . hasMore ( ) ; ) {
FrameIterator : : Element e = it . next ( c ) ;
addMultiRead ( c , e . value , e . sizeInBytes , state , & count ) ;
2008-09-13 21:09:26 +00:00
}
2008-09-15 02:28:42 +00:00
2008-09-20 23:42:46 +00:00
state - > readCount = count ;
allocateTargets ( c , state ) ;
2008-04-20 19:35:36 +00:00
}
2008-09-13 21:09:26 +00:00
2008-09-15 02:28:42 +00:00
return state ;
2008-04-20 19:35:36 +00:00
}
2008-02-11 17:21:41 +00:00
void
2008-10-14 00:18:18 +00:00
restoreState ( Context * c , ForkState * s )
2007-12-11 23:52:28 +00:00
{
2008-09-15 02:28:42 +00:00
if ( c - > logicalIp > = 0 and c - > logicalCode [ c - > logicalIp ] - > lastEvent = = 0 ) {
appendDummy ( c ) ;
}
2008-09-13 21:09:26 +00:00
c - > stack = s - > stack ;
c - > locals = s - > locals ;
2008-09-20 23:42:46 +00:00
c - > predecessor = s - > predecessor ;
2008-09-22 14:28:18 +00:00
c - > logicalIp = s - > logicalIp ;
2008-09-13 21:09:26 +00:00
2008-09-20 23:42:46 +00:00
if ( c - > predecessor ) {
2008-10-14 00:18:18 +00:00
c - > forkState = s ;
2008-09-20 23:42:46 +00:00
allocateTargets ( c , s ) ;
2008-09-07 20:12:11 +00:00
}
2008-05-04 20:55:34 +00:00
}
2008-11-01 19:14:13 +00:00
Value *
maybeBuddy ( Context * c , Value * v , unsigned sizeInBytes )
{
if ( v - > local ) {
Value * n = value ( c ) ;
appendBuddy ( c , v , n , sizeInBytes ) ;
return n ;
} else {
return v ;
}
}
2008-03-13 23:43:11 +00:00
class Client : public Assembler : : Client {
public :
Client ( Context * c ) : c ( c ) { }
2008-05-06 21:13:02 +00:00
virtual int acquireTemporary ( uint32_t mask ) {
2008-05-12 13:54:47 +00:00
int r = pickRegister ( c , mask ) - > number ;
2008-04-30 15:44:17 +00:00
save ( r ) ;
2008-04-20 00:43:12 +00:00
increment ( c , r ) ;
2008-03-13 23:43:11 +00:00
return r ;
}
virtual void releaseTemporary ( int r ) {
2008-05-12 13:54:47 +00:00
decrement ( c , c - > registers [ r ] ) ;
2008-04-30 15:44:17 +00:00
restore ( r ) ;
2008-03-13 23:43:11 +00:00
}
2008-04-27 20:15:18 +00:00
virtual void save ( int r ) {
2008-10-15 00:45:31 +00:00
Register * reg = c - > registers [ r ] ;
if ( reg - > refCount or reg - > value ) {
releaseRegister ( c , r ) ;
}
assert ( c , reg - > refCount = = 0 ) ;
assert ( c , reg - > value = = 0 ) ;
2008-04-27 20:15:18 +00:00
}
2008-09-05 15:00:38 +00:00
virtual void restore ( int ) {
// todo
2008-04-27 20:15:18 +00:00
}
2008-03-13 23:43:11 +00:00
Context * c ;
} ;
2007-12-08 23:22:13 +00:00
class MyCompiler : public Compiler {
public :
2008-05-31 22:14:27 +00:00
MyCompiler ( System * s , Assembler * assembler , Zone * zone ,
Compiler : : Client * compilerClient ) :
c ( s , assembler , zone , compilerClient ) , client ( & c )
2008-03-13 23:43:11 +00:00
{
assembler - > setClient ( & client ) ;
}
2007-12-08 23:22:13 +00:00
2008-09-13 21:09:26 +00:00
virtual State * saveState ( ) {
return : : saveState ( & c ) ;
2008-04-28 15:53:48 +00:00
}
2008-09-13 21:09:26 +00:00
virtual void restoreState ( State * state ) {
2008-10-14 00:18:18 +00:00
: : restoreState ( & c , static_cast < ForkState * > ( state ) ) ;
2008-04-28 15:53:48 +00:00
}
2008-05-19 04:31:52 +00:00
virtual void init ( unsigned logicalCodeLength , unsigned parameterFootprint ,
2008-09-28 19:00:52 +00:00
unsigned localFootprint , unsigned alignedFrameSize )
2008-05-19 04:31:52 +00:00
{
2008-02-11 17:21:41 +00:00
c . logicalCodeLength = logicalCodeLength ;
2008-05-19 04:31:52 +00:00
c . parameterFootprint = parameterFootprint ;
c . localFootprint = localFootprint ;
2008-09-28 19:00:52 +00:00
c . alignedFrameSize = alignedFrameSize ;
2008-05-19 04:31:52 +00:00
2008-09-28 21:56:12 +00:00
unsigned frameResourceSize = sizeof ( FrameResource )
* ( alignedFrameSize + parameterFootprint ) ;
c . frameResources = static_cast < FrameResource * >
( c . zone - > allocate ( frameResourceSize ) ) ;
memset ( c . frameResources , 0 , frameResourceSize ) ;
2008-08-16 17:45:36 +00:00
c . logicalCode = static_cast < LogicalInstruction * * >
( c . zone - > allocate ( sizeof ( LogicalInstruction * ) * logicalCodeLength ) ) ;
memset ( c . logicalCode , 0 , sizeof ( LogicalInstruction * ) * logicalCodeLength ) ;
2008-05-19 04:31:52 +00:00
2008-09-24 00:01:42 +00:00
c . locals = static_cast < Local * >
( c . zone - > allocate ( sizeof ( Local ) * localFootprint ) ) ;
2008-09-09 00:31:19 +00:00
2008-09-24 00:01:42 +00:00
memset ( c . locals , 0 , sizeof ( Local ) * localFootprint ) ;
2007-12-17 20:55:31 +00:00
}
2008-02-11 17:21:41 +00:00
virtual void visitLogicalIp ( unsigned logicalIp ) {
2008-09-15 02:28:42 +00:00
assert ( & c , logicalIp < c . logicalCodeLength ) ;
Event * e = c . logicalCode [ logicalIp ] - > firstEvent ;
2008-10-04 17:26:35 +00:00
Event * p = c . predecessor ;
if ( p ) {
p - > stackAfter = c . stack ;
p - > localsAfter = c . locals ;
2008-10-14 00:18:18 +00:00
Link * link = : : link
( & c , p , e - > predecessors , e , p - > successors , c . forkState ) ;
e - > predecessors = link ;
p - > successors = link ;
2008-10-15 00:45:31 +00:00
c . lastEvent - > visitLinks = cons ( & c , link , c . lastEvent - > visitLinks ) ;
2008-10-14 00:18:18 +00:00
fprintf ( stderr , " populate junction reads for %d to %d \n " ,
p - > logicalInstruction - > index , logicalIp ) ;
populateJunctionReads ( & c , e - > predecessors ) ;
2008-09-15 02:28:42 +00:00
}
2008-10-14 00:18:18 +00:00
c . forkState = false ;
2007-12-08 23:22:13 +00:00
}
2008-02-11 17:21:41 +00:00
virtual void startLogicalIp ( unsigned logicalIp ) {
2008-09-15 02:28:42 +00:00
assert ( & c , logicalIp < c . logicalCodeLength ) ;
assert ( & c , c . logicalCode [ logicalIp ] = = 0 ) ;
2008-09-13 21:09:26 +00:00
if ( c . logicalIp > = 0 and c . logicalCode [ c . logicalIp ] - > lastEvent = = 0 ) {
appendDummy ( & c ) ;
}
2008-04-20 19:35:36 +00:00
2008-10-06 00:50:59 +00:00
Event * p = c . predecessor ;
if ( p ) {
p - > stackAfter = c . stack ;
p - > localsAfter = c . locals ;
}
2008-09-15 02:28:42 +00:00
c . logicalCode [ logicalIp ] = new
( c . zone - > allocate ( sizeof ( LogicalInstruction ) ) )
LogicalInstruction ( logicalIp , c . stack , c . locals ) ;
2008-04-20 19:35:36 +00:00
2008-02-11 17:21:41 +00:00
c . logicalIp = logicalIp ;
2007-12-26 16:56:14 +00:00
}
2008-02-11 17:21:41 +00:00
virtual Promise * machineIp ( unsigned logicalIp ) {
return new ( c . zone - > allocate ( sizeof ( IpPromise ) ) ) IpPromise ( & c , logicalIp ) ;
2007-12-26 16:56:14 +00:00
}
2008-02-11 17:21:41 +00:00
virtual Promise * poolAppend ( intptr_t value ) {
2008-03-13 20:50:56 +00:00
return poolAppendPromise ( resolved ( & c , value ) ) ;
2007-12-26 16:56:14 +00:00
}
2008-02-11 17:21:41 +00:00
virtual Promise * poolAppendPromise ( Promise * value ) {
Promise * p = new ( c . zone - > allocate ( sizeof ( PoolPromise ) ) )
PoolPromise ( & c , c . constantCount ) ;
2007-12-08 23:22:13 +00:00
2008-02-11 17:21:41 +00:00
ConstantPoolNode * constant
= new ( c . zone - > allocate ( sizeof ( ConstantPoolNode ) ) )
ConstantPoolNode ( value ) ;
2007-12-16 00:24:15 +00:00
2008-02-11 17:21:41 +00:00
if ( c . firstConstant ) {
c . lastConstant - > next = constant ;
} else {
c . firstConstant = constant ;
2007-12-16 00:24:15 +00:00
}
2008-02-11 17:21:41 +00:00
c . lastConstant = constant ;
+ + c . constantCount ;
2007-12-12 22:19:13 +00:00
2008-02-11 17:21:41 +00:00
return p ;
2007-12-08 23:22:13 +00:00
}
2008-02-11 17:21:41 +00:00
virtual Operand * constant ( int64_t value ) {
2008-03-13 20:50:56 +00:00
return promiseConstant ( resolved ( & c , value ) ) ;
2007-12-08 23:22:13 +00:00
}
2008-02-11 17:21:41 +00:00
virtual Operand * promiseConstant ( Promise * value ) {
2008-04-20 19:35:36 +00:00
return : : value ( & c , : : constantSite ( & c , value ) ) ;
2007-12-08 23:22:13 +00:00
}
2008-02-11 17:21:41 +00:00
virtual Operand * address ( Promise * address ) {
2008-04-20 19:35:36 +00:00
return value ( & c , : : addressSite ( & c , address ) ) ;
2007-12-08 23:22:13 +00:00
}
2008-02-11 17:21:41 +00:00
virtual Operand * memory ( Operand * base ,
int displacement = 0 ,
Operand * index = 0 ,
2008-04-13 19:48:20 +00:00
unsigned scale = 1 )
2008-02-11 17:21:41 +00:00
{
2008-04-17 22:07:32 +00:00
Value * result = value ( & c ) ;
2008-03-15 23:54:20 +00:00
2008-04-17 20:48:26 +00:00
appendMemory ( & c , static_cast < Value * > ( base ) , displacement ,
static_cast < Value * > ( index ) , scale , result ) ;
2008-03-15 23:54:20 +00:00
return result ;
2007-12-08 23:22:13 +00:00
}
2008-02-11 17:21:41 +00:00
virtual Operand * stack ( ) {
2008-09-05 15:00:38 +00:00
Site * s = registerSite ( & c , c . arch - > stack ( ) ) ;
2008-04-26 20:56:03 +00:00
return value ( & c , s , s ) ;
2007-12-08 23:22:13 +00:00
}
2008-09-05 15:00:38 +00:00
virtual Operand * thread ( ) {
Site * s = registerSite ( & c , c . arch - > thread ( ) ) ;
2008-04-26 20:56:03 +00:00
return value ( & c , s , s ) ;
2007-12-08 23:22:13 +00:00
}
2008-09-05 15:00:38 +00:00
virtual Operand * stackTop ( ) {
2008-10-25 02:12:02 +00:00
Site * s = frameSite
2008-11-01 19:14:13 +00:00
( & c , frameIndex
( & c , c . stack - > index + c . localFootprint , c . stack - > sizeInWords ) ) ;
2008-04-26 20:56:03 +00:00
return value ( & c , s , s ) ;
2007-12-08 23:22:13 +00:00
}
2007-12-31 22:40:56 +00:00
Promise * machineIp ( ) {
2008-08-16 17:45:36 +00:00
return codePromise ( & c , c . logicalCode [ c . logicalIp ] - > lastEvent ) ;
2007-12-31 22:40:56 +00:00
}
2008-11-01 19:14:13 +00:00
virtual void push ( unsigned sizeInBytes ) {
assert ( & c , ceiling ( sizeInBytes , BytesPerWord ) ) ;
2008-04-27 20:15:18 +00:00
2008-11-01 19:14:13 +00:00
c . stack = : : stack
( & c , value ( & c ) , ceiling ( sizeInBytes , BytesPerWord ) , c . stack ) ;
2008-04-26 20:56:03 +00:00
}
2008-11-01 19:14:13 +00:00
virtual void push ( unsigned sizeInBytes , Operand * value ) {
: : push ( & c , sizeInBytes , maybeBuddy
( & c , static_cast < Value * > ( value ) , sizeInBytes ) ) ;
2007-12-22 00:26:55 +00:00
}
2007-12-09 22:45:43 +00:00
2008-11-01 19:14:13 +00:00
virtual Operand * pop ( unsigned sizeInBytes ) {
return : : pop ( & c , sizeInBytes ) ;
2007-12-08 23:22:13 +00:00
}
2008-07-05 20:21:13 +00:00
virtual void pushed ( ) {
Value * v = value ( & c ) ;
2008-09-25 00:48:32 +00:00
appendFrameSite
2008-10-04 17:26:35 +00:00
( & c , v , BytesPerWord ,
2008-10-25 02:12:02 +00:00
frameIndex ( & c , ( c . stack ? c . stack - > index : 0 ) + c . localFootprint , 1 ) ) ;
2008-09-25 00:48:32 +00:00
2008-09-13 21:09:26 +00:00
c . stack = : : stack ( & c , v , 1 , c . stack ) ;
2007-12-26 16:56:14 +00:00
}
2008-07-05 20:21:13 +00:00
virtual void popped ( ) {
2008-09-13 21:09:26 +00:00
c . stack = c . stack - > next ;
2008-07-05 20:21:13 +00:00
}
virtual StackElement * top ( ) {
2008-09-13 21:09:26 +00:00
return c . stack ;
2008-07-05 20:21:13 +00:00
}
virtual unsigned size ( StackElement * e ) {
2008-11-01 19:14:13 +00:00
return static_cast < Stack * > ( e ) - > sizeInWords ;
2008-07-05 20:21:13 +00:00
}
virtual unsigned padding ( StackElement * e ) {
2008-11-01 19:14:13 +00:00
return static_cast < Stack * > ( e ) - > paddingInWords ;
2007-12-08 23:22:13 +00:00
}
2008-11-01 19:14:13 +00:00
virtual Operand * peek ( unsigned sizeInBytes UNUSED , unsigned index ) {
2008-09-13 21:09:26 +00:00
Stack * s = c . stack ;
2008-02-17 20:57:40 +00:00
for ( unsigned i = index ; i > 0 ; ) {
2008-11-01 19:14:13 +00:00
i - = s - > sizeInWords ;
2008-04-29 16:55:56 +00:00
s = s - > next ;
2008-02-17 20:57:40 +00:00
}
2008-11-01 19:14:13 +00:00
assert ( & c , s - > sizeInWords = = ceiling ( sizeInBytes , BytesPerWord ) ) ;
2008-04-17 20:48:26 +00:00
return s - > value ;
2007-12-26 16:56:14 +00:00
}
2008-02-11 17:21:41 +00:00
virtual Operand * call ( Operand * address ,
unsigned flags ,
TraceHandler * traceHandler ,
2008-04-18 04:16:20 +00:00
unsigned resultSize ,
2008-02-11 17:21:41 +00:00
unsigned argumentCount ,
. . . )
{
va_list a ; va_start ( a , argumentCount ) ;
2007-12-11 00:48:09 +00:00
2008-02-11 17:21:41 +00:00
unsigned footprint = 0 ;
2008-02-12 02:06:12 +00:00
unsigned size = BytesPerWord ;
2008-04-17 20:48:26 +00:00
Value * arguments [ argumentCount ] ;
unsigned argumentSizes [ argumentCount ] ;
2008-09-05 15:00:38 +00:00
int index = 0 ;
2008-02-11 17:21:41 +00:00
for ( unsigned i = 0 ; i < argumentCount ; + + i ) {
2008-04-17 20:48:26 +00:00
Value * o = va_arg ( a , Value * ) ;
2008-02-12 02:06:12 +00:00
if ( o ) {
2008-04-17 20:48:26 +00:00
arguments [ index ] = o ;
argumentSizes [ index ] = size ;
2008-02-12 02:06:12 +00:00
size = BytesPerWord ;
2008-04-17 20:48:26 +00:00
+ + index ;
2008-02-12 02:06:12 +00:00
} else {
size = 8 ;
}
+ + footprint ;
2007-12-31 22:40:56 +00:00
}
2007-12-08 23:22:13 +00:00
2008-02-11 17:21:41 +00:00
va_end ( a ) ;
2007-12-26 16:56:14 +00:00
2008-09-13 21:09:26 +00:00
Stack * oldStack = c . stack ;
2008-07-05 20:21:13 +00:00
Stack * bottomArgument = 0 ;
2008-04-18 03:47:42 +00:00
2008-04-29 16:40:44 +00:00
for ( int i = index - 1 ; i > = 0 ; - - i ) {
2008-04-18 03:47:42 +00:00
: : push ( & c , argumentSizes [ i ] , arguments [ i ] ) ;
2008-07-05 20:21:13 +00:00
if ( i = = index - 1 ) {
2008-09-13 21:09:26 +00:00
bottomArgument = c . stack ;
2008-07-05 20:21:13 +00:00
}
2008-04-18 03:47:42 +00:00
}
2008-09-13 21:09:26 +00:00
Stack * argumentStack = c . stack ;
c . stack = oldStack ;
2008-04-18 03:47:42 +00:00
2008-07-05 20:21:13 +00:00
Value * result = value ( & c ) ;
appendCall ( & c , static_cast < Value * > ( address ) , flags , traceHandler , result ,
2008-08-23 18:04:36 +00:00
resultSize , argumentStack , index , 0 ) ;
2008-07-05 20:21:13 +00:00
return result ;
}
virtual Operand * stackCall ( Operand * address ,
unsigned flags ,
TraceHandler * traceHandler ,
unsigned resultSize ,
unsigned argumentFootprint )
{
2008-04-17 20:48:26 +00:00
Value * result = value ( & c ) ;
2008-07-05 20:21:13 +00:00
appendCall ( & c , static_cast < Value * > ( address ) , flags , traceHandler , result ,
2008-09-13 21:09:26 +00:00
resultSize , c . stack , 0 , argumentFootprint ) ;
2008-02-11 17:21:41 +00:00
return result ;
2007-12-26 16:56:14 +00:00
}
2008-02-12 02:06:12 +00:00
virtual void return_ ( unsigned size , Operand * value ) {
2008-04-17 20:48:26 +00:00
appendReturn ( & c , size , static_cast < Value * > ( value ) ) ;
2007-12-26 16:56:14 +00:00
}
2008-09-25 00:48:32 +00:00
virtual void initLocal ( unsigned size , unsigned index ) {
assert ( & c , index < c . localFootprint ) ;
2008-09-24 00:01:42 +00:00
2008-09-09 00:31:19 +00:00
Value * v = value ( & c ) ;
2008-10-25 02:12:02 +00:00
fprintf ( stderr , " init local %p of size %d at %d (%d) \n " , v , size , index ,
frameIndex ( & c , index , ceiling ( size , BytesPerWord ) ) ) ;
appendFrameSite
( & c , v , size , frameIndex ( & c , index , ceiling ( size , BytesPerWord ) ) ) ;
2008-09-24 00:01:42 +00:00
Local * local = c . locals + index ;
local - > value = v ;
2008-11-01 19:14:13 +00:00
local - > sizeInBytes = size ;
2008-09-09 00:31:19 +00:00
}
2008-09-25 00:48:32 +00:00
virtual void initLocalsFromLogicalIp ( unsigned logicalIp ) {
assert ( & c , logicalIp < c . logicalCodeLength ) ;
unsigned footprint = sizeof ( Local ) * c . localFootprint ;
Local * newLocals = static_cast < Local * > ( c . zone - > allocate ( footprint ) ) ;
memset ( newLocals , 0 , footprint ) ;
c . locals = newLocals ;
2008-09-24 00:01:42 +00:00
2008-09-25 00:48:32 +00:00
Event * e = c . logicalCode [ logicalIp ] - > firstEvent ;
for ( unsigned i = 0 ; i < c . localFootprint ; + + i ) {
2008-10-04 17:26:35 +00:00
Local * local = e - > localsBefore + i ;
2008-09-25 00:48:32 +00:00
if ( local - > value ) {
2008-11-01 19:14:13 +00:00
initLocal ( local - > sizeInBytes , i ) ;
2008-09-25 00:48:32 +00:00
}
}
}
2008-11-01 19:14:13 +00:00
virtual void storeLocal ( unsigned sizeInBytes , Operand * src , unsigned index ) {
2008-05-19 04:31:52 +00:00
assert ( & c , index < c . localFootprint ) ;
2008-05-20 19:11:42 +00:00
2008-11-01 19:14:13 +00:00
Local * local = c . locals + index ;
if ( local - > value ) local - > value - > local = false ;
2008-09-24 00:01:42 +00:00
unsigned footprint = sizeof ( Local ) * c . localFootprint ;
Local * newLocals = static_cast < Local * > ( c . zone - > allocate ( footprint ) ) ;
memcpy ( newLocals , c . locals , footprint ) ;
2008-09-13 21:09:26 +00:00
c . locals = newLocals ;
2008-09-25 00:48:32 +00:00
// fprintf(stderr, "store local %p of size %d at %d\n", src, size, index);
2008-11-01 19:14:13 +00:00
local = c . locals + index ;
local - > value = maybeBuddy ( & c , static_cast < Value * > ( src ) , sizeInBytes ) ;
local - > value - > local = true ;
local - > sizeInBytes = sizeInBytes ;
2008-05-19 04:31:52 +00:00
}
2008-11-01 19:14:13 +00:00
virtual Operand * loadLocal ( unsigned sizeInBytes UNUSED , unsigned index ) {
2008-05-19 04:31:52 +00:00
assert ( & c , index < c . localFootprint ) ;
2008-09-24 00:01:42 +00:00
assert ( & c , c . locals [ index ] . value ) ;
2008-11-01 19:14:13 +00:00
assert ( & c , pad ( c . locals [ index ] . sizeInBytes ) = = pad ( sizeInBytes ) ) ;
2008-05-20 19:11:42 +00:00
2008-09-25 00:48:32 +00:00
// fprintf(stderr, "load local %p of size %d at %d\n",
// c.locals[index].value, size, index);
2008-09-24 00:01:42 +00:00
return c . locals [ index ] . value ;
2008-05-19 04:31:52 +00:00
}
2008-05-31 22:14:27 +00:00
virtual void checkBounds ( Operand * object , unsigned lengthOffset ,
Operand * index , intptr_t handler )
{
appendBoundsCheck ( & c , static_cast < Value * > ( object ) ,
lengthOffset , static_cast < Value * > ( index ) , handler ) ;
}
2008-02-12 02:06:12 +00:00
virtual void store ( unsigned size , Operand * src , Operand * dst ) {
2008-04-17 20:48:26 +00:00
appendMove ( & c , Move , size , static_cast < Value * > ( src ) ,
2008-09-05 15:00:38 +00:00
size , static_cast < Value * > ( dst ) ) ;
2007-12-26 16:56:14 +00:00
}
2008-02-12 02:06:12 +00:00
virtual Operand * load ( unsigned size , Operand * src ) {
2008-04-17 20:48:26 +00:00
Value * dst = value ( & c ) ;
2008-09-05 15:00:38 +00:00
appendMove ( & c , Move , size , static_cast < Value * > ( src ) , size , dst ) ;
2008-02-11 17:21:41 +00:00
return dst ;
2007-12-08 23:22:13 +00:00
}
2008-02-12 02:06:12 +00:00
virtual Operand * loadz ( unsigned size , Operand * src ) {
2008-04-17 20:48:26 +00:00
Value * dst = value ( & c ) ;
2008-09-05 15:00:38 +00:00
appendMove ( & c , MoveZ , size , static_cast < Value * > ( src ) , size , dst ) ;
2008-02-11 17:21:41 +00:00
return dst ;
2007-12-08 23:22:13 +00:00
}
2008-02-11 17:21:41 +00:00
virtual Operand * load4To8 ( Operand * src ) {
2008-04-17 20:48:26 +00:00
Value * dst = value ( & c ) ;
2008-09-05 15:00:38 +00:00
appendMove ( & c , Move , 4 , static_cast < Value * > ( src ) , 8 , dst ) ;
2008-02-11 17:21:41 +00:00
return dst ;
2007-12-08 23:22:13 +00:00
}
2008-06-12 16:56:48 +00:00
virtual Operand * lcmp ( Operand * a , Operand * b ) {
Value * result = value ( & c ) ;
appendCombine ( & c , LongCompare , 8 , static_cast < Value * > ( a ) ,
2008-09-05 15:00:38 +00:00
8 , static_cast < Value * > ( b ) , 8 , result ) ;
2008-06-12 16:56:48 +00:00
return result ;
}
2008-02-12 02:06:12 +00:00
virtual void cmp ( unsigned size , Operand * a , Operand * b ) {
2008-04-17 20:48:26 +00:00
appendCompare ( & c , size , static_cast < Value * > ( a ) ,
static_cast < Value * > ( b ) ) ;
2007-12-08 23:22:13 +00:00
}
2008-02-11 17:21:41 +00:00
virtual void jl ( Operand * address ) {
2008-04-17 20:48:26 +00:00
appendBranch ( & c , JumpIfLess , static_cast < Value * > ( address ) ) ;
2007-12-08 23:22:13 +00:00
}
2008-02-11 17:21:41 +00:00
virtual void jg ( Operand * address ) {
2008-04-17 20:48:26 +00:00
appendBranch ( & c , JumpIfGreater , static_cast < Value * > ( address ) ) ;
2007-12-08 23:22:13 +00:00
}
2008-02-11 17:21:41 +00:00
virtual void jle ( Operand * address ) {
2008-04-17 20:48:26 +00:00
appendBranch ( & c , JumpIfLessOrEqual , static_cast < Value * > ( address ) ) ;
2007-12-08 23:22:13 +00:00
}
2008-02-11 17:21:41 +00:00
virtual void jge ( Operand * address ) {
2008-04-17 20:48:26 +00:00
appendBranch ( & c , JumpIfGreaterOrEqual , static_cast < Value * > ( address ) ) ;
2007-12-08 23:22:13 +00:00
}
2008-02-11 17:21:41 +00:00
virtual void je ( Operand * address ) {
2008-04-17 20:48:26 +00:00
appendBranch ( & c , JumpIfEqual , static_cast < Value * > ( address ) ) ;
2007-12-26 16:56:14 +00:00
}
2008-02-11 17:21:41 +00:00
virtual void jne ( Operand * address ) {
2008-04-17 20:48:26 +00:00
appendBranch ( & c , JumpIfNotEqual , static_cast < Value * > ( address ) ) ;
2007-12-26 16:56:14 +00:00
}
2008-02-11 17:21:41 +00:00
virtual void jmp ( Operand * address ) {
2008-04-17 22:07:32 +00:00
appendBranch ( & c , Jump , static_cast < Value * > ( address ) ) ;
2007-12-09 22:45:43 +00:00
}
2008-02-12 02:06:12 +00:00
virtual Operand * add ( unsigned size , Operand * a , Operand * b ) {
2008-04-17 20:48:26 +00:00
Value * result = value ( & c ) ;
appendCombine ( & c , Add , size , static_cast < Value * > ( a ) ,
2008-09-05 15:00:38 +00:00
size , static_cast < Value * > ( b ) , size , result ) ;
2008-02-11 17:21:41 +00:00
return result ;
2007-12-09 22:45:43 +00:00
}
2008-02-12 02:06:12 +00:00
virtual Operand * sub ( unsigned size , Operand * a , Operand * b ) {
2008-04-17 20:48:26 +00:00
Value * result = value ( & c ) ;
appendCombine ( & c , Subtract , size , static_cast < Value * > ( a ) ,
2008-09-05 15:00:38 +00:00
size , static_cast < Value * > ( b ) , size , result ) ;
2008-02-11 17:21:41 +00:00
return result ;
2007-12-23 00:00:35 +00:00
}
2008-02-12 02:06:12 +00:00
virtual Operand * mul ( unsigned size , Operand * a , Operand * b ) {
2008-04-17 20:48:26 +00:00
Value * result = value ( & c ) ;
appendCombine ( & c , Multiply , size , static_cast < Value * > ( a ) ,
2008-09-05 15:00:38 +00:00
size , static_cast < Value * > ( b ) , size , result ) ;
2008-02-11 17:21:41 +00:00
return result ;
2007-12-08 23:22:13 +00:00
}
2008-02-12 02:06:12 +00:00
virtual Operand * div ( unsigned size , Operand * a , Operand * b ) {
2008-04-17 20:48:26 +00:00
Value * result = value ( & c ) ;
appendCombine ( & c , Divide , size , static_cast < Value * > ( a ) ,
2008-09-05 15:00:38 +00:00
size , static_cast < Value * > ( b ) , size , result ) ;
2008-02-11 17:21:41 +00:00
return result ;
2007-12-22 00:26:55 +00:00
}
2008-02-12 02:06:12 +00:00
virtual Operand * rem ( unsigned size , Operand * a , Operand * b ) {
2008-04-17 20:48:26 +00:00
Value * result = value ( & c ) ;
appendCombine ( & c , Remainder , size , static_cast < Value * > ( a ) ,
2008-09-05 15:00:38 +00:00
size , static_cast < Value * > ( b ) , size , result ) ;
2008-02-11 17:21:41 +00:00
return result ;
2007-12-26 16:56:14 +00:00
}
2008-02-12 02:06:12 +00:00
virtual Operand * shl ( unsigned size , Operand * a , Operand * b ) {
2008-04-17 20:48:26 +00:00
Value * result = value ( & c ) ;
2008-09-05 15:00:38 +00:00
appendCombine ( & c , ShiftLeft , BytesPerWord , static_cast < Value * > ( a ) ,
size , static_cast < Value * > ( b ) , size , result ) ;
2008-02-11 17:21:41 +00:00
return result ;
2007-12-26 16:56:14 +00:00
}
2008-02-12 02:06:12 +00:00
virtual Operand * shr ( unsigned size , Operand * a , Operand * b ) {
2008-04-17 20:48:26 +00:00
Value * result = value ( & c ) ;
2008-09-05 15:00:38 +00:00
appendCombine ( & c , ShiftRight , BytesPerWord , static_cast < Value * > ( a ) ,
size , static_cast < Value * > ( b ) , size , result ) ;
2008-02-11 17:21:41 +00:00
return result ;
2007-12-26 16:56:14 +00:00
}
2008-02-12 02:06:12 +00:00
virtual Operand * ushr ( unsigned size , Operand * a , Operand * b ) {
2008-04-17 20:48:26 +00:00
Value * result = value ( & c ) ;
2008-09-05 15:00:38 +00:00
appendCombine ( & c , UnsignedShiftRight , BytesPerWord , static_cast < Value * > ( a ) ,
size , static_cast < Value * > ( b ) , size , result ) ;
2008-02-11 17:21:41 +00:00
return result ;
2007-12-08 23:22:13 +00:00
}
2008-02-12 02:06:12 +00:00
virtual Operand * and_ ( unsigned size , Operand * a , Operand * b ) {
2008-04-17 20:48:26 +00:00
Value * result = value ( & c ) ;
appendCombine ( & c , And , size , static_cast < Value * > ( a ) ,
2008-09-05 15:00:38 +00:00
size , static_cast < Value * > ( b ) , size , result ) ;
2008-02-11 17:21:41 +00:00
return result ;
2007-12-08 23:22:13 +00:00
}
2008-02-12 02:06:12 +00:00
virtual Operand * or_ ( unsigned size , Operand * a , Operand * b ) {
2008-04-17 20:48:26 +00:00
Value * result = value ( & c ) ;
appendCombine ( & c , Or , size , static_cast < Value * > ( a ) ,
2008-09-05 15:00:38 +00:00
size , static_cast < Value * > ( b ) , size , result ) ;
2008-02-11 17:21:41 +00:00
return result ;
2007-12-12 18:59:45 +00:00
}
2008-02-12 02:06:12 +00:00
virtual Operand * xor_ ( unsigned size , Operand * a , Operand * b ) {
2008-04-17 20:48:26 +00:00
Value * result = value ( & c ) ;
appendCombine ( & c , Xor , size , static_cast < Value * > ( a ) ,
2008-09-05 15:00:38 +00:00
size , static_cast < Value * > ( b ) , size , result ) ;
2008-02-11 17:21:41 +00:00
return result ;
2007-12-08 23:22:13 +00:00
}
2008-02-12 02:06:12 +00:00
virtual Operand * neg ( unsigned size , Operand * a ) {
2008-04-17 20:48:26 +00:00
Value * result = value ( & c ) ;
appendTranslate ( & c , Negate , size , static_cast < Value * > ( a ) , result ) ;
2008-02-11 17:21:41 +00:00
return result ;
2007-12-08 23:22:13 +00:00
}
2008-02-11 17:21:41 +00:00
virtual unsigned compile ( ) {
2008-09-23 21:18:41 +00:00
return c . machineCodeSize = : : compile ( & c ) ;
2007-12-11 23:52:28 +00:00
}
virtual unsigned poolSize ( ) {
2008-03-11 16:40:28 +00:00
return c . constantCount * BytesPerWord ;
2007-12-11 00:48:09 +00:00
}
2008-02-11 17:21:41 +00:00
virtual void writeTo ( uint8_t * dst ) {
c . machineCode = dst ;
2008-09-05 15:00:38 +00:00
c . assembler - > writeTo ( dst ) ;
2007-12-11 23:52:28 +00:00
2008-02-11 17:21:41 +00:00
int i = 0 ;
for ( ConstantPoolNode * n = c . firstConstant ; n ; n = n - > next ) {
2008-09-23 21:18:41 +00:00
* reinterpret_cast < intptr_t * > ( dst + pad ( c . machineCodeSize ) + i )
2008-02-11 17:21:41 +00:00
= n - > promise - > value ( ) ;
2008-04-20 19:35:36 +00:00
i + = BytesPerWord ;
2007-12-16 00:24:15 +00:00
}
2007-12-08 23:22:13 +00:00
}
virtual void dispose ( ) {
2008-02-11 17:21:41 +00:00
// ignore
2007-12-08 23:22:13 +00:00
}
2007-12-09 20:03:21 +00:00
Context c ;
2008-05-31 22:14:27 +00:00
: : Client client ;
2007-12-08 23:22:13 +00:00
} ;
} // namespace
namespace vm {
Compiler *
2008-05-06 21:13:02 +00:00
makeCompiler ( System * system , Assembler * assembler , Zone * zone ,
2008-05-31 22:14:27 +00:00
Compiler : : Client * client )
2007-12-08 23:22:13 +00:00
{
2007-12-31 22:40:56 +00:00
return new ( zone - > allocate ( sizeof ( MyCompiler ) ) )
2008-05-31 22:14:27 +00:00
MyCompiler ( system , assembler , zone , client ) ;
2007-12-08 23:22:13 +00:00
}
2008-02-11 17:21:41 +00:00
} // namespace vm