mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
731 lines
18 KiB
731 lines
18 KiB
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ptrana.cxx
|
|
|
|
Abstract:
|
|
|
|
Contains implementations of analysis routines for pointer types.
|
|
|
|
Notes:
|
|
|
|
|
|
History:
|
|
|
|
Oct-10-1993 VibhasC Created
|
|
|
|
----------------------------------------------------------------------------*/
|
|
|
|
/****************************************************************************
|
|
* include files
|
|
***************************************************************************/
|
|
#include "allana.hxx"
|
|
#pragma hdrstop
|
|
/****************************************************************************
|
|
* local definitions
|
|
***************************************************************************/
|
|
/****************************************************************************
|
|
* local data
|
|
***************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* externs
|
|
***************************************************************************/
|
|
/****************************************************************************/
|
|
|
|
CG_STATUS
|
|
CG_POINTER::UnMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
CG_STATUS Status;
|
|
|
|
// Unmarshall the pointer body first. If the pointer needs to be deferred,
|
|
// then dont perform the pointee unmarshall analysis. Just indicate that
|
|
// there is a pointee that needs to be unmarshalled later.
|
|
|
|
Status = PtrUnMarshallAnalysis( pAna );
|
|
|
|
if( pAna->IsPointeeDeferred() )
|
|
{
|
|
pAna->SetHasAtLeastOneDeferredPointee();
|
|
}
|
|
else
|
|
Status = PteUnMarshallAnalysis( pAna );
|
|
|
|
return Status;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_POINTER::PtrUnMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
RPC_BUF_SIZE_PROPERTY BSizeProp = BSIZE_FIXED;
|
|
RPC_BUFFER_SIZE BufIncr = 0;
|
|
unsigned short EProp = E_SIZING_POSSIBLE |
|
|
E_UNMARSHALL_POSSIBLE;
|
|
long MarshallWeight = 0;
|
|
ALIGNMENT_PROPERTY CurAl = pAna->GetCurAlignmentState();
|
|
unsigned short CurEmbedLevel = pAna->GetCurrentEmbeddingLevel();
|
|
BOOL fTopLevelPtr = (CurEmbedLevel == 0);
|
|
|
|
// Perform the analysis for the pointer body. For a [ref] pointer, nothing
|
|
// needs to be done.
|
|
|
|
if( IsRef() && !pAna->IsMemoryAllocDone() )
|
|
{
|
|
SetUAction( RecommendUAction( pAna->GetCurrentSide(),
|
|
pAna->IsMemoryAllocDone(),
|
|
pAna->IsRefAllocDone(),
|
|
FALSE, // no buffer re-use for ref.
|
|
UAFLAGS_NONE
|
|
));
|
|
|
|
}
|
|
else // unique or ptr.
|
|
{
|
|
|
|
// Bump the marshalling pointer by the alignment of the pointer itself.
|
|
|
|
CurAl = pAna->Advance( GetWireAlignment(),
|
|
(STM_ACTION *)0,
|
|
&BSizeProp,
|
|
&BufIncr
|
|
);
|
|
|
|
}
|
|
|
|
pAna->SetEngineProperty( EProp );
|
|
pAna->AddMarshallWeight( MarshallWeight );
|
|
pAna->SetRpcBufSizeProperty( BSizeProp );
|
|
pAna->SetCurAlignmentState( CurAl );
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_POINTER::PteUnMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
CG_STATUS Status;
|
|
pAna->PushIndirectionLevel();
|
|
|
|
Status = CorePteUnMarshallAnalysis( pAna );
|
|
|
|
pAna->PopIndirectionLevel();
|
|
|
|
pAna->IncrRpcBufferSize(pAna->Position(
|
|
pAna->GetNextWireAlignment(),
|
|
(STM_ACTION*)0 )
|
|
);
|
|
|
|
return Status;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_POINTER::MarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
CG_STATUS Status;
|
|
short EmbedLevel;
|
|
|
|
// Marshall the pointer body first. If the pointee needs to be deferred,
|
|
// dont perform marshall analysis on the pointee. Just indicate that a
|
|
// pointee needs to be marshalled later.
|
|
|
|
Status = PtrMarshallAnalysis( pAna );
|
|
|
|
if( pAna->IsPointeeDeferred() )
|
|
{
|
|
pAna->SetHasAtLeastOneDeferredPointee();
|
|
}
|
|
else
|
|
{
|
|
EmbedLevel = pAna->GetCurrentEmbeddingLevel();
|
|
pAna->ResetEmbeddingLevel();
|
|
Status = PteMarshallAnalysis( pAna );
|
|
pAna->SetCurrentEmbeddingLevel( EmbedLevel );
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_POINTER::PtrMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
ALIGNMENT_PROPERTY CurAl = pAna->GetCurAlignmentState();
|
|
RPC_BUFFER_SIZE BufIncr = 0;
|
|
RPC_BUF_SIZE_PROPERTY BSizeProp = BSIZE_FIXED;
|
|
unsigned short EProp =
|
|
E_SIZING_POSSIBLE | E_MARSHALL_POSSIBLE;
|
|
unsigned short MarshallWeight= IsRef() ? 0 :
|
|
IsUnique() ? MW_UNIQUE_PTR :
|
|
MW_FULL_PTR;
|
|
|
|
if( !IsRef() )
|
|
{
|
|
CurAl = pAna->Advance( AL_4,
|
|
(STM_ACTION *)0,
|
|
&BSizeProp,
|
|
&BufIncr
|
|
);
|
|
|
|
pAna->IncrRpcBufferSize( BufIncr + 4 );
|
|
}
|
|
|
|
pAna->SetCurAlignmentState( CurAl );
|
|
pAna->SetRpcBufSizeProperty( BSizeProp );
|
|
pAna->SetEngineProperty( EProp );
|
|
pAna->AddMarshallWeight( MarshallWeight );
|
|
|
|
// Set the alignment of the machine to be the next expected alignment
|
|
// After the pointer or pointee is unmarshalled, the next alignment state
|
|
// adjusted to.
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_POINTER::PteMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
CG_STATUS Status;
|
|
|
|
pAna->PushIndirectionLevel();
|
|
|
|
pAna->SetMemoryAllocDone(); // Needed ?
|
|
Status = CorePteMarshallAnalysis( pAna );
|
|
|
|
pAna->PopIndirectionLevel();
|
|
|
|
return Status;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_POINTER::FollowerMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
return PteMarshallAnalysis( pAna );
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_POINTER::FollowerUnMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
return PteUnMarshallAnalysis( pAna );
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_POINTER::S_OutLocalAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Perform analysis for [out] params that need to be allocated as locals
|
|
on server stub.
|
|
|
|
Arguments:
|
|
|
|
pAna - The analysis block.
|
|
|
|
Return Value:
|
|
|
|
CG_OK if all is well
|
|
error otherwise.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
CG_STATUS Status = CG_OK;
|
|
CG_NDR * pC = (CG_NDR *)GetNonGenericHandleChild();
|
|
|
|
if( !pAna->IsMemoryAllocDone() )
|
|
{
|
|
if( pAna->GetCurrentSide() != C_SIDE )
|
|
{
|
|
PNAME pName = pAna->GenTempResourceName( 0 );
|
|
SetResource( pAna->AddLocalResource( pName,
|
|
MakeIDNode( pName, GetType() )
|
|
));
|
|
}
|
|
SetAllocatedOnStack( 1 );
|
|
}
|
|
|
|
// If it is a ref pointer, chase it further.
|
|
|
|
if( IsRef() && !IsQualifiedPointer() )
|
|
{
|
|
pAna->ResetMemoryAllocDone();
|
|
pAna->SetRefAllocDone();
|
|
Status = pC->S_OutLocalAnalysis( pAna );
|
|
}
|
|
|
|
// If this is the server side, and the pointee is allocated on stack,
|
|
// then dont free the pointee, else free it.
|
|
|
|
if( pC->IsAllocatedOnStack() )
|
|
{
|
|
SetPointerShouldFree( 0 );
|
|
}
|
|
return Status;
|
|
}
|
|
CG_STATUS
|
|
CG_POINTER::InLocalAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
if( IsRef() )
|
|
{
|
|
((CG_NDR *)GetChild())->InLocalAnalysis( pAna );
|
|
}
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* CG_QUALIFIED_POINTER
|
|
***************************************************************************/
|
|
|
|
CG_STATUS
|
|
CG_QUALIFIED_POINTER::CorePteMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Perform the core pointee marshall analysis for a conformant string
|
|
|
|
Arguments:
|
|
|
|
pAna - The analysis block pointer.
|
|
|
|
Return Value:
|
|
|
|
CG_OK if all is well, error otherwise.
|
|
|
|
Notes:
|
|
|
|
The ndr for a conformant string (eg typedef [string] char *p ) is:
|
|
- MaxCount
|
|
- Offset from start of the valid character
|
|
- Actual Count.
|
|
|
|
We need to declare a local variable which will hold the length of the
|
|
string, so that the length can be used in the actual marshall for memcopy.
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
node_skl * pType;
|
|
ALIGNMENT_PROPERTY Al;
|
|
RPC_BUFFER_SIZE BufIncr = 0;
|
|
PNAME pResName;
|
|
BOOL fNeedsCount;
|
|
BOOL fNeedsFirstAndLength;
|
|
RPC_BUFFER_SIZE TotalHdrSize = 0;
|
|
|
|
|
|
if( pAna->IsArrayContext() )
|
|
{
|
|
SetUsedInArray();
|
|
}
|
|
|
|
if( fNeedsCount = NeedsMaxCountMarshall() )
|
|
{
|
|
if( !GetSizeResource() )
|
|
{
|
|
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
|
|
pResName = pAna->GenTempResourceName(0);
|
|
pType = MakeIDNode( pResName, pType );
|
|
SetSizeResource( pAna->AddTransientResource( pResName, pType ) );
|
|
}
|
|
else
|
|
{
|
|
pAna->AddTransientResource( GetSizeResource()->GetResourceName(),
|
|
GetSizeResource()->GetType()
|
|
);
|
|
}
|
|
TotalHdrSize += 4;
|
|
}
|
|
|
|
if( fNeedsFirstAndLength = NeedsFirstAndLengthMarshall() )
|
|
{
|
|
if( !GetLengthResource() )
|
|
{
|
|
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
|
|
pResName = pAna->GenTempResourceName(0);
|
|
pType = MakeIDNode( pResName, pType );
|
|
SetLengthResource( pAna->AddTransientResource( pResName, pType ) );
|
|
}
|
|
else
|
|
{
|
|
pAna->AddTransientResource( GetLengthResource()->GetResourceName(),
|
|
GetLengthResource()->GetType()
|
|
);
|
|
}
|
|
|
|
if( NeedsExplicitFirst() )
|
|
{
|
|
if( !GetFirstResource() )
|
|
{
|
|
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
|
|
pResName = pAna->GenTempResourceName(0);
|
|
pType = MakeIDNode( pResName, pType );
|
|
SetFirstResource( pAna->AddTransientResource( pResName, pType ) );
|
|
}
|
|
else
|
|
{
|
|
pAna->AddTransientResource(GetLengthResource()->GetResourceName(),
|
|
GetLengthResource()->GetType()
|
|
);
|
|
}
|
|
}
|
|
TotalHdrSize += (4 + 4);
|
|
}
|
|
|
|
// Adjust alignment for the first long. The size is the alignment
|
|
// increment, and 4 longs. The buffer size property is unknown since
|
|
// the length of the string is unknown. Therefore the sizing code will
|
|
// have to be generated for this.
|
|
|
|
if( fNeedsCount )
|
|
pAna->Advance( AL_4, 0, 0, 0 );
|
|
|
|
if( fNeedsFirstAndLength )
|
|
{
|
|
pAna->Advance( AL_4, 0, 0, 0 );
|
|
pAna->Advance( AL_4, 0, 0, 0 );
|
|
}
|
|
|
|
// Depending upon the type of the string, figure out the worst case
|
|
// alignment after the string is marshalled.
|
|
|
|
Al = ((CG_NDR *)GetChild())->GetWireAlignment();
|
|
|
|
pAna->Advance( Al,
|
|
(STM_ACTION *)0,
|
|
(RPC_BUF_SIZE_PROPERTY *)0,
|
|
&BufIncr
|
|
);
|
|
|
|
pAna->SetCurAlignmentState( MAKE_WC_ALIGNMENT( Al ) );
|
|
|
|
pAna->SetRpcBufSizeProperty( BSIZE_UNKNOWN );
|
|
pAna->IncrRpcBufferSize( BufIncr + TotalHdrSize );
|
|
pAna->SetEngineProperty( E_SIZING_POSSIBLE | E_MARSHALL_POSSIBLE );
|
|
pAna->AddMarshallWeight( MW_CONFORMANT_STRING );
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_QUALIFIED_POINTER::CorePteUnMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
RPC_BUFFER_SIZE BufIncr = 0;
|
|
ALIGNMENT_PROPERTY Al;
|
|
node_skl * pType;
|
|
PNAME pResName;
|
|
BOOL fNeedsMaxCount;
|
|
BOOL fNeedsFirstAndLength;
|
|
|
|
|
|
// If a resource for the length has not already been allocated, allocate
|
|
// one.
|
|
|
|
if( fNeedsMaxCount = NeedsMaxCountMarshall() )
|
|
{
|
|
if( !GetSizeResource() )
|
|
{
|
|
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
|
|
pResName = pAna->GenTempResourceName(0);
|
|
pType = MakeIDNode( pResName, pType );
|
|
|
|
SetSizeResource( pAna->AddTransientResource( pResName, pType ) );
|
|
}
|
|
else
|
|
pAna->AddTransientResource( GetSizeResource()->GetResourceName(),
|
|
GetSizeResource()->GetType()
|
|
);
|
|
pAna->Advance( AL_4, 0, 0, 0 );
|
|
}
|
|
|
|
if( fNeedsFirstAndLength = NeedsFirstAndLengthMarshall() )
|
|
{
|
|
if( !GetLengthResource() )
|
|
{
|
|
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
|
|
pResName = pAna->GenTempResourceName(0);
|
|
pType = MakeIDNode( pResName, pType );
|
|
|
|
SetLengthResource( pAna->AddTransientResource( pResName, pType ) );
|
|
}
|
|
else
|
|
pAna->AddTransientResource( GetLengthResource()->GetResourceName(),
|
|
GetLengthResource()->GetType()
|
|
);
|
|
|
|
if( NeedsExplicitFirst() )
|
|
{
|
|
if( !GetFirstResource() )
|
|
{
|
|
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
|
|
pResName = pAna->GenTempResourceName(0);
|
|
pType = MakeIDNode( pResName, pType );
|
|
|
|
SetFirstResource( pAna->AddTransientResource( pResName, pType ) );
|
|
}
|
|
else
|
|
pAna->AddTransientResource(GetFirstResource()->GetResourceName(),
|
|
GetFirstResource()->GetType()
|
|
);
|
|
}
|
|
pAna->Advance( AL_4, 0, 0, 0 );
|
|
pAna->Advance( AL_4, 0, 0, 0 );
|
|
}
|
|
|
|
|
|
// Depending upon the type of the pointee, figure out the worst case
|
|
// alignment after the string is marshalled.
|
|
|
|
Al = ((CG_NDR *)GetChild())->GetWireAlignment();
|
|
|
|
pAna->Advance( Al,
|
|
(STM_ACTION *)0,
|
|
(RPC_BUF_SIZE_PROPERTY * )0,
|
|
&BufIncr
|
|
);
|
|
|
|
// Set up the rest of the properties.
|
|
|
|
pAna->SetCurAlignmentState( MAKE_WC_ALIGNMENT( Al ) );
|
|
pAna->SetRpcBufSizeProperty( BSIZE_UNKNOWN );
|
|
pAna->SetEngineProperty( E_SIZING_POSSIBLE | E_MARSHALL_POSSIBLE );
|
|
pAna->AddMarshallWeight( MW_CONFORMANT_STRING );
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_INTERFACE_POINTER::S_OutLocalAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Perform analysis for out params, allocated as locals on the server side.
|
|
|
|
Arguments:
|
|
|
|
pAna - A pointer to the analysis block.
|
|
|
|
Return Value:
|
|
|
|
CG_OK if all is well
|
|
error otherwise.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
if( pAna->IsRefAllocDone() )
|
|
{
|
|
if( pAna->GetCurrentSide() != C_SIDE )
|
|
{
|
|
PNAME pName = pAna->GenTempResourceName( 0 );
|
|
node_skl * pType = GetType();
|
|
|
|
node_skl * pActualType;
|
|
|
|
if ( pType->NodeKind() == NODE_DEF )
|
|
pActualType = MakeIDNode( pName, pType );
|
|
else
|
|
pActualType = MakePtrIDNode( pName, pType );
|
|
|
|
SetResource( pAna->AddLocalResource( pName,
|
|
pActualType ));
|
|
}
|
|
|
|
SetAllocatedOnStack( 1 );
|
|
}
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_INTERFACE_POINTER::MarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Perform marshall analysis for interface ptr.
|
|
|
|
Arguments:
|
|
|
|
pCCB - The code gen controller block.
|
|
|
|
Return Value:
|
|
|
|
CG_OK
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
pAna->SetRpcBufSizeProperty( BSIZE_UNKNOWN );
|
|
return CG_OK;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* utility functions
|
|
***************************************************************************/
|
|
U_ACTION
|
|
CG_POINTER::RecommendUAction(
|
|
SIDE CurrentSide,
|
|
BOOL fMemoryAllocated,
|
|
BOOL fRefAllocated,
|
|
BOOL fBufferReUsePossible,
|
|
UAFLAGS AdditionalFlags )
|
|
{
|
|
U_ACTION UAction = CG_NDR::RecommendUAction( CurrentSide,
|
|
fMemoryAllocated,
|
|
fRefAllocated,
|
|
fBufferReUsePossible,
|
|
AdditionalFlags );
|
|
return UAction;
|
|
|
|
}
|
|
|
|
#define a0 ADD_0
|
|
#define a1 ADD_1
|
|
#define a2 ADD_2
|
|
#define a3 ADD_3
|
|
#define a4 ADD_4
|
|
#define a5 ADD_5
|
|
#define a6 ADD_6
|
|
#define a7 ADD_7
|
|
|
|
#define f2 FAL_2
|
|
#define f4 FAL_4
|
|
#define f8 FAL_8
|
|
|
|
|
|
// Action mask specifying what to do within if, within else and outside the if
|
|
|
|
|
|
#define am(i,e,o) ((((i << 4) | e ) << 4) | o)
|
|
|
|
#define GET_WITHIN_IF( a ) ((a >> 8) & 0xf)
|
|
#define GET_WITHIN_ELSE( a ) ((a >> 4) & 0xf)
|
|
#define GET_OUTSIDE_IF( a ) (a & 0xf)
|
|
|
|
// NOTE:: the 6th row and column entry here (index 5) is a dummy entry
|
|
|
|
unsigned short AdjustArray[11][11] =
|
|
{
|
|
{
|
|
am(a0,a0,a0),am(a1,a0,a0),am(a2,a0,a0),am(a3,a0,a0),am(a4,a0,a0),am(a0,a0,a0)
|
|
,am(a6,a0,a0),am(a7,a0,a0),am(f2,a0,a0),am(f4,a0,a0),am(f8,a0,a0)
|
|
}
|
|
|
|
, {
|
|
am(a0,a1,a0),am(a0,a0,a1),am(a1,a0,a1),am(a2,a0,a1),am(a3,a0,a2),am(a0,a0,a0)
|
|
,am(a5,a0,a1),am(a6,a0,a1),am(f2,a1,a0),am(f4,a1,a0),am(f8,a1,a0)
|
|
}
|
|
|
|
, {
|
|
am(a0,a2,a0),am(a1,a2,a0),am(a0,a0,a2),am(a1,a0,a2),am(a2,a0,a2),am(a0,a0,a0)
|
|
,am(a4,a0,a2),am(a5,a0,a2),am(f2,a2,a0),am(f4,a2,a0),am(f8,a2,a0)
|
|
}
|
|
|
|
, {
|
|
am(a0,a3,a0),am(a1,a3,a0),am(a2,a3,a0),am(a0,a0,a3),am(a1,a0,a3),am(a0,a0,a0)
|
|
,am(a3,a0,a3),am(a4,a0,a3),am(f2,a3,a0),am(f4,a3,a0),am(f8,a3,a0)
|
|
}
|
|
|
|
, {
|
|
am(a0,a4,a0),am(a1,a4,a0),am(a2,a4,a0),am(a3,a4,a0),am(a0,a0,a4),am(a0,a0,a0)
|
|
,am(a2,a0,a4),am(a3,a0,a4),am(f2,a4,a0),am(f4,a4,a0),am(f8,a4,a0)
|
|
}
|
|
|
|
, {
|
|
am(a0,a0,a0),am(a0,a0,a0),am(a0,a0,a0),am(a0,a0,a0),am(a0,a0,a0),am(a0,a0,a0)
|
|
,am(a0,a0,a0),am(a0,a0,a0),am(a0,a0,a0),am(a0,a0,a0),am(a0,a0,a0)
|
|
}
|
|
|
|
, {
|
|
am(a0,a6,a0),am(a1,a6,a0),am(a2,a6,a0),am(a3,a6,a0),am(a4,a6,a0),am(a0,a0,a0)
|
|
,am(a0,a0,a6),am(a1,a0,a6),am(f2,a6,a0),am(f4,a6,a0),am(f8,a6,a0)
|
|
}
|
|
|
|
, {
|
|
am(a0,a7,a0),am(a1,a7,a0),am(a2,a7,a0),am(a3,a7,a0),am(a4,a7,a0),am(a0,a0,a0)
|
|
,am(a6,a7,a0),am(a0,a0,a7),am(f2,a7,a0),am(f4,a7,a0),am(f8,a7,a0)
|
|
}
|
|
|
|
, {
|
|
am(a0,f2,a0),am(a1,f2,a0),am(a2,f2,a0),am(a2,f2,a0),am(a4,f2,a0),am(a0,a0,a0)
|
|
,am(a6,f2,a0),am(a7,f2,a0),am(a0,a0,f2),am(f4,f2,a0),am(f8,f2,a0)
|
|
}
|
|
|
|
, {
|
|
am(a0,f4,a0),am(a1,f4,a0),am(a2,f4,a0),am(a3,f4,a0),am(a4,f4,a0),am(a0,a0,a0)
|
|
,am(a6,f4,a0),am(a7,f4,a0),am(f2,f4,a0),am(a0,a0,f4),am(f8,f4,a0)
|
|
}
|
|
|
|
, {
|
|
am(a0,f8,a0),am(a2,f8,a0),am(a2,f8,a0),am(a3,f8,a0),am(a4,f8,a0),am(a0,a0,a0)
|
|
,am(a6,f8,a0),am(a7,f8,a0),am(f2,f8,a0),am(f4,f8,a0),am(a0,a0,f8)
|
|
}
|
|
};
|
|
|
|
unsigned short FAXlat[] =
|
|
{
|
|
5 // dummy
|
|
,7 // FAL_2
|
|
,8 // FAL_4
|
|
,9 // FAL_8
|
|
};
|
|
|
|
void
|
|
CG_POINTER::RecommendAlignmentAdjustment(
|
|
ALIGNMENT_PROPERTY AlBeforePteMarshall,
|
|
ALIGNMENT_PROPERTY AlAfterPteMarshall,
|
|
ALIGNMENT_PROPERTY TargetAlignment,
|
|
STM_ACTION * ActionInIfClause,
|
|
STM_ACTION * ActionInElseClause,
|
|
STM_ACTION * ActionOutsideIfClause )
|
|
{
|
|
ALSTMC Al;
|
|
STM_ACTION ActionIfNoPteMarshall;
|
|
STM_ACTION ActionAfterPteMarshall;
|
|
unsigned short Index1,Index2;
|
|
unsigned short Entry;
|
|
|
|
|
|
Al.SetCurrentState( AlBeforePteMarshall );
|
|
|
|
Al.Position( TargetAlignment, &ActionIfNoPteMarshall );
|
|
|
|
Al.SetCurrentState( AlAfterPteMarshall );
|
|
|
|
Al.Position( TargetAlignment, &ActionAfterPteMarshall );
|
|
|
|
|
|
if( IS_FORCED_ALIGNMENT_ACTION( ActionIfNoPteMarshall ) )
|
|
Index1 = FAXlat[ (ActionIfNoPteMarshall & ~FAL_MASK ) ];
|
|
else
|
|
Index1 = ActionIfNoPteMarshall;
|
|
|
|
if( IS_FORCED_ALIGNMENT_ACTION( ActionAfterPteMarshall ) )
|
|
Index2 = FAXlat[ (ActionAfterPteMarshall & ~FAL_MASK ) ];
|
|
else
|
|
Index2 = ActionAfterPteMarshall;
|
|
|
|
Entry = AdjustArray[ Index1 ][ Index2 ];
|
|
|
|
*ActionInIfClause = GET_WITHIN_IF( Entry );
|
|
*ActionInElseClause = GET_WITHIN_ELSE( Entry );
|
|
*ActionOutsideIfClause = GET_OUTSIDE_IF( Entry );
|
|
}
|