Leaked source code of windows server 2003
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.
 
 
 
 
 
 

387 lines
12 KiB

dnl----------------------------------------------------------------------------
dnl
dnl x86 assembly code generating macros for attribute handlers.
dnl
dnl Copyright (C) Microsoft Corporation, 1997.
dnl
dnl----------------------------------------------------------------------------
dnl
dnl d_AddAttrsCode
dnl
dnl Macro to generate fld/fadd/fstp for each argument with
dnl pipelining across all arguments.
dnl Achieves complete pipelining with four arguments, so
dnl care should be taken to batch up at least four things.
dnl A max of seven things should be added to avoid FP stack overflow.
dnl
define(`d_AddAttrsCodeLoop',
` fld DWORD PTR [ecx+d_Nth1($1, d_shift(d_shift($@)))]
fadd DWORD PTR [edx+d_Nth1($1, d_shift(d_shift($@)))]
ifelse(eval($2 > 1), `1',
`d_AddAttrsCodeLoop(incr($1), decr($2), d_shift(d_shift($@)))')dnl
ifelse(eval($1 > $2), `1',
` fxch st(eval($1 - $2))
')dnl
fstp DWORD PTR [ecx+d_Nth1($2, d_shift(d_shift($@)))]
')dnl
define(`d_AddAttrsCode', `d_AddAttrsCodeLoop(`1', $#, $@)')dnl
dnl
dnl d_AddScaledAttrsCode
dnl
dnl Macro to generate fld/fmul/fadd/fstp for each argument with
dnl pipelining across all arguments.
dnl Achieves complete pipelining with four arguments, so
dnl care should be taken to batch up at least four things.
dnl A max of seven things should be added to avoid FP stack overflow.
dnl
define(`d_AddScaledAttrsLoadLoop',
` fld DWORD PTR [edx+d_Nth1($1, d_shift(d_shift($@)))]
fmul fScaleVal
ifelse(eval($2 > 1), `1',
`d_AddScaledAttrsLoadLoop(incr($1), decr($2), d_shift(d_shift($@)))')dnl
ifelse(eval($1 > 1), `1',
` fxch st(decr($1))
',
` fxch st(decr($2))
')dnl
fld DWORD PTR [ecx+d_Nth1($2, d_shift(d_shift($@)))]
faddp st(1), st(0)
')dnl
define(`d_AddScaledAttrsStoreLoop',
`ifelse(eval($2 > 1), `1',
`d_AddScaledAttrsStoreLoop(incr($1), decr($2), d_shift(d_shift($@)))')dnl
ifelse(eval($1 > $2), `1',
` fxch st(eval($1 - $2))
')dnl
ifelse($1, `1',
` fxch st(1)
')dnl
fstp DWORD PTR [ecx+d_Nth1($2, d_shift(d_shift($@)))]
')dnl
define(`d_AddScaledAttrsCode',
`d_AddScaledAttrsLoadLoop(`1', $#, $@)dnl
d_AddScaledAttrsStoreLoop(`0', $#, $@)')dnl
dnl
dnl d_AddFloatAttrsBody
dnl
dnl Generates the body of an FP attribute adder routine.
dnl Attributes are processed in cache order as much as possible.
dnl
dnl $1 is one of Z_Diff, Z_Diff_Spec, Z_Diff_Tex1, Z_Diff_Spec_Tex1,
dnl Z_Tex1_Tex2, Z_DIdx, Z_DIdx_Tex1, Z_Tex1.
dnl
define(`d_AddFloatAttrsBody',
`
; Add surface pointers.
mov eax, [edx+ATTRSET_ipSurface]
add eax, [ecx+ATTRSET_pSurface]
mov [ecx+ATTRSET_pSurface], eax
mov eax, [edx+ATTRSET_ipZ]
add eax, [ecx+ATTRSET_pZ]
mov [ecx+ATTRSET_pZ], eax
; Do FP additions.
ifelse(`$1', `Z_Diff',
`d_AddAttrsCode(`ATTRSET_fZ', `ATTRSET_fB',
`ATTRSET_fG', `ATTRSET_fR',
`ATTRSET_fA')dnl
')dnl
ifelse(`$1', `Z_Diff_Spec',
`d_AddAttrsCode(`ATTRSET_fZ', `ATTRSET_fB',
`ATTRSET_fG', `ATTRSET_fR')dnl
d_AddAttrsCode(`ATTRSET_fA', `ATTRSET_fBS',
`ATTRSET_fGS', `ATTRSET_fRS')dnl
')dnl
ifelse(`$1', `Z_Diff_Tex1',
`d_AddAttrsCode(`ATTRSET_fZ', `ATTRSET_fOoW',
`ATTRSET_fUoW1', `ATTRSET_fVoW1')dnl
d_AddAttrsCode(`ATTRSET_fB', `ATTRSET_fG',
`ATTRSET_fR', `ATTRSET_fA')dnl
')dnl
ifelse(`$1', `Z_Diff_Spec_Tex1',
`d_AddAttrsCode(`ATTRSET_fZ', `ATTRSET_fOoW',
`ATTRSET_fUoW1', `ATTRSET_fVoW1',
`ATTRSET_fB')dnl
d_AddAttrsCode(`ATTRSET_fG', `ATTRSET_fR',
`ATTRSET_fA', `ATTRSET_fBS',
`ATTRSET_fGS', `ATTRSET_fRS')dnl
')dnl
ifelse(`$1', `Z_Tex1_Tex2',
`d_AddAttrsCode(`ATTRSET_fZ', `ATTRSET_fOoW',
`ATTRSET_fUoW1', `ATTRSET_fVoW1',
`ATTRSET_fUoW2', `ATTRSET_fVoW2')dnl
')dnl
ifelse(`$1', `Z_DIdx',
`d_AddAttrsCode(`ATTRSET_fZ',
`ATTRSET_fDIdx', `ATTRSET_fDIdxA')dnl
')dnl
ifelse(`$1', `Z_DIdx_Tex1',
`d_AddAttrsCode(`ATTRSET_fZ', `ATTRSET_fOoW',
`ATTRSET_fUoW1', `ATTRSET_fVoW1',
`ATTRSET_fDIdx', `ATTRSET_fDIdxA')dnl
')dnl
ifelse(`$1', `Z_Tex1',
`d_AddAttrsCode(`ATTRSET_fZ', `ATTRSET_fOoW',
`ATTRSET_fUoW1', `ATTRSET_fVoW1')dnl
')dnl
')dnl
dnl
dnl d_AddFixedAttrsBody
dnl
dnl Generates the body of a fixed attribute adder routine.
dnl Attributes are processed in cache order as much as possible.
dnl
dnl $1 contains substrings Z, Diff, Spec, DIdx, Tex1 and Tex2 in any mix.
dnl
define(`d_AddFixedAttrsBody',
`
; Add surface pointers.
mov eax, [edx+ATTRSET_ipSurface]
add eax, [ecx+ATTRSET_pSurface]
mov [ecx+ATTRSET_pSurface], eax
mov eax, [edx+ATTRSET_ipZ]
add eax, [ecx+ATTRSET_pZ]
mov [ecx+ATTRSET_pZ], eax
; Add attributes.
ifelse(eval(d_index(`$1', `Z') >= 0), `1',
`
mov eax, [edx+ATTRSET_iZ]
add eax, [ecx+ATTRSET_iZ]
mov [ecx+ATTRSET_iZ], eax
')dnl
ifelse(eval(d_index(`$1', `Tex') >= 0), `1',
`
mov eax, [edx+ATTRSET_iOoW]
add eax, [ecx+ATTRSET_iOoW]
mov [ecx+ATTRSET_iOoW], eax
mov eax, [edx+ATTRSET_iUoW1]
add eax, [ecx+ATTRSET_iUoW1]
mov [ecx+ATTRSET_iUoW1], eax
mov eax, [edx+ATTRSET_iVoW1]
add eax, [ecx+ATTRSET_iVoW1]
mov [ecx+ATTRSET_iVoW1], eax
')dnl
ifelse(eval(d_index(`$1', `Tex2') >= 0), `1',
`
mov eax, [edx+ATTRSET_iUoW2]
add eax, [ecx+ATTRSET_iUoW2]
mov [ecx+ATTRSET_iUoW2], eax
mov eax, [edx+ATTRSET_iVoW2]
add eax, [ecx+ATTRSET_iVoW2]
mov [ecx+ATTRSET_iVoW2], eax
')dnl
ifelse(eval(d_index(`$1', `Diff') >= 0), `1',
`
mov eax, [edx+ATTRSET_iB]
add eax, [ecx+ATTRSET_iB]
mov [ecx+ATTRSET_iB], eax
mov eax, [edx+ATTRSET_iG]
add eax, [ecx+ATTRSET_iG]
mov [ecx+ATTRSET_iG], eax
mov eax, [edx+ATTRSET_iR]
add eax, [ecx+ATTRSET_iR]
mov [ecx+ATTRSET_iR], eax
mov eax, [edx+ATTRSET_iA]
add eax, [ecx+ATTRSET_iA]
mov [ecx+ATTRSET_iA], eax
')dnl
ifelse(eval(d_index(`$1', `Spec') >= 0), `1',
`
mov eax, [edx+ATTRSET_iBS]
add eax, [ecx+ATTRSET_iBS]
mov [ecx+ATTRSET_iBS], eax
mov eax, [edx+ATTRSET_iGS]
add eax, [ecx+ATTRSET_iGS]
mov [ecx+ATTRSET_iGS], eax
mov eax, [edx+ATTRSET_iRS]
add eax, [ecx+ATTRSET_iRS]
mov [ecx+ATTRSET_iRS], eax
')dnl
ifelse(eval(d_index(`$1', `DIdx') >= 0), `1',
`
mov eax, [edx+ATTRSET_iDIdx]
add eax, [ecx+ATTRSET_iDIdx]
mov [ecx+ATTRSET_iDIdx], eax
mov eax, [edx+ATTRSET_iDIdxA]
add eax, [ecx+ATTRSET_iDIdxA]
mov [ecx+ATTRSET_iDIdxA], eax
')dnl
')dnl
dnl
dnl d_FillSpanFloatAttrsBody
dnl
dnl Generates the body of a FP span filler routine.
dnl Suboptimal cache ordering due to attempt to overlap OoW divide with
dnl integer ops.
dnl
dnl $1 contains substrings Z, Diff, Spec, DIdx, Tex1 and Tex2 in any mix.
dnl
define(`d_FillSpanFloatAttrsBody',
`ifelse(eval(d_index(`$1', `Tex') >= 0), `1',
`
fld DWORD PTR [ecx+ATTRSET_fOoW]
fist DWORD PTR [edx+RASTSPAN_iOoW]
fdivr DWORD PTR OOW_W_SCALE
')dnl
; Set surface pointers.
mov eax, [ecx+ATTRSET_pSurface]
mov [edx+RASTSPAN_pSurface], eax
mov eax, [ecx+ATTRSET_pZ]
mov [edx+RASTSPAN_pZ], eax
ifelse(eval(d_index(`$1', `Tex') >= 0), `1',
`
; Clears both iLOD and iDLOD.
xor eax, eax
mov [edx+RASTSPAN_iLOD], eax
fistp DWORD PTR [edx+RASTSPAN_iW]
fld DWORD PTR [ecx+ATTRSET_fUoW1]
fistp DWORD PTR [edx+RASTSPAN_iUoW1]
fld DWORD PTR [ecx+ATTRSET_fVoW1]
fistp DWORD PTR [edx+RASTSPAN_iVoW1]
')dnl
ifelse(eval(d_index(`$1', `Tex2') >= 0), `1',
`
fld DWORD PTR [ecx+ATTRSET_fUoW2]
fistp DWORD PTR [edx+RASTSPAN_iUoW2]
fld DWORD PTR [ecx+ATTRSET_fVoW2]
fistp DWORD PTR [edx+RASTSPAN_iVoW2]
')dnl
ifelse(eval(d_index(`$1', `Z') >= 0), `1',
`
fld DWORD PTR [ecx+ATTRSET_fZ]
fistp DWORD PTR [edx+RASTSPAN_uZ]
')dnl
ifelse(eval(d_index(`$1', `Diff') >= 0), `1',
`
; Directly store DWORD-aligned fields, then whack in
; half DWORDs.
; ATTENTION - 8.8 color fields could use the FP fixing trick
; to use fstp instead of fistp. Adds could be overlapped
; so itd be free cycles?
fld DWORD PTR [ecx+ATTRSET_fG]
fistp DWORD PTR iVal
fld DWORD PTR [ecx+ATTRSET_fB]
fistp DWORD PTR [edx+RASTSPAN_uB]
mov ax, WORD PTR iVal
fld DWORD PTR [ecx+ATTRSET_fA]
fistp DWORD PTR iVal
mov WORD PTR [edx+RASTSPAN_uG], ax
fld DWORD PTR [ecx+ATTRSET_fR]
fistp DWORD PTR [edx+RASTSPAN_uR]
mov ax, WORD PTR iVal
mov WORD PTR [edx+RASTSPAN_uA], ax
')dnl
ifelse(eval(d_index(`$1', `Spec') >= 0), `1',
`
fld DWORD PTR [ecx+ATTRSET_fGS]
fistp DWORD PTR iVal
fld DWORD PTR [ecx+ATTRSET_fBS]
fistp DWORD PTR [edx+RASTSPAN_uBS]
mov ax, WORD PTR iVal
mov WORD PTR [edx+RASTSPAN_uGS], ax
; Trashes uFog, but thats OK because fog isnt getting used.
fld DWORD PTR [ecx+ATTRSET_fRS]
fistp DWORD PTR [edx+RASTSPAN_uRS]
')dnl
ifelse(eval(d_index(`$1', `DIdx') >= 0), `1',
`
fld DWORD PTR [ecx+ATTRSET_fDIdx]
fistp DWORD PTR [edx+RASTSPAN_iIdx]
fld DWORD PTR [ecx+ATTRSET_fDIdxA]
fistp DWORD PTR [edx+RASTSPAN_iIdxA]
')dnl
')dnl
dnl
dnl d_FillSpanFixedAttrsBody
dnl
dnl Generates the body of a fixed span filler routine.
dnl Cache ordered except for the overlap of the OoW divide.
dnl
dnl $1 contains substrings Z, Diff, Spec, DIdx, Tex1 and Tex2 in any mix.
dnl
define(`d_FillSpanFixedAttrsBody',
`ifelse(eval(d_index(`$1', `Tex') >= 0), `1',
`
fild DWORD PTR [ecx+ATTRSET_iOoW]
fdivr DWORD PTR OOW_W_SCALE
')dnl
; Set surface pointers.
mov eax, [ecx+ATTRSET_pSurface]
mov [edx+RASTSPAN_pSurface], eax
mov eax, [ecx+ATTRSET_pZ]
mov [edx+RASTSPAN_pZ], eax
ifelse(eval(d_index(`$1', `Z') >= 0), `1',
`
mov eax, [ecx+ATTRSET_uZ]
mov [edx+RASTSPAN_uZ], eax
')dnl
ifelse(eval(d_index(`$1', `Tex') >= 0), `1',
`
; Clears both iLOD and iDLOD.
xor eax, eax
mov [edx+RASTSPAN_iLOD], eax
mov eax, [ecx+ATTRSET_iOoW]
mov [edx+RASTSPAN_iOoW], eax
mov eax, [ecx+ATTRSET_iUoW1]
mov [edx+RASTSPAN_iUoW1], eax
mov eax, [ecx+ATTRSET_iVoW1]
mov [edx+RASTSPAN_iVoW1], eax
')dnl
ifelse(eval(d_index(`$1', `Tex2') >= 0), `1',
`
mov eax, [ecx+ATTRSET_iUoW2]
mov [edx+RASTSPAN_iUoW2], eax
mov eax, [ecx+ATTRSET_iVoW2]
mov [edx+RASTSPAN_iVoW2], eax
')dnl
ifelse(eval(d_index(`$1', `Diff') >= 0), `1',
`
; Directly store DWORD-aligned fields, then whack in
; half DWORDs.
; ATTENTION - Keep word pairs shifted and OR together to store
; as DWORDs instead?
mov eax, [ecx+ATTRSET_uB]
mov [edx+RASTSPAN_uB], eax
mov eax, [ecx+ATTRSET_uR]
mov [edx+RASTSPAN_uR], eax
mov ax, [ecx+ATTRSET_uG]
mov [edx+RASTSPAN_uG], ax
mov ax, [ecx+ATTRSET_uA]
mov [edx+RASTSPAN_uA], ax
')dnl
ifelse(eval(d_index(`$1', `Spec') >= 0), `1',
`
mov eax, [ecx+ATTRSET_uBS]
mov [edx+RASTSPAN_uBS], eax
mov eax, [ecx+ATTRSET_uRS]
mov [edx+RASTSPAN_uRS], eax
mov ax, [ecx+ATTRSET_uGS]
mov [edx+RASTSPAN_uGS], ax
')dnl
ifelse(eval(d_index(`$1', `DIdx') >= 0), `1',
`
mov eax, [ecx+ATTRSET_uDIdx]
mov [edx+RASTSPAN_iIdx], eax
mov eax, [ecx+ATTRSET_uDIdxA]
mov [edx+RASTSPAN_iIdxA], eax
')dnl
ifelse(eval(d_index(`$1', `Tex') >= 0), `1',
`
fistp DWORD PTR [edx+RASTSPAN_iW]
')dnl
')dnl