⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arrays.hhf

📁 High Level assembly language(HLA)软件
💻 HHF
📖 第 1 页 / 共 5 页
字号:
	// Index:	Compute the row-major index into an array	//		 	given a list of indexes.	//	//			Handles both normal arrays and dynamically	//			declared arrays.	#macro index( _register_, _arrayVar_, _indicies_[] ):			_numDims_,			_i_,			_elementSize_,			_tempid_,			_pType_;		#if( !@IsReg32( _register_ ))			#error( "index: First parameter must be a 32-bit register" );		#elseif( array.isItDynamic( _arrayVar_ ))			// We've probably got a dynamic array at this point.			// (there is the slight chance the user declared a			// record containing these fields, but this is highly			// unlikely.			#if			( 					@elements( _arrayVar_.dopeVector ) 				<>	@elements( _indicies_ )			)				#error				( 					@tostring:_arrayVar_ + 					" has " + 					string( _numDims_ ) +					" dimensions, you provided " +					string( @elements( _indicies_ )) +					" dimensions"				);			#else				?_i_ := 1;				mov( @text( _indicies_[0] ), _register_ );				#if( array.boundsChk )					if( _register_ < @dim( _arrayVar_ )[0] ) then						raise( ex.ArrayBounds );					endif;				#endif				#while( _i_ < @elements( _arrayVar_.dopeVector ))					intmul( _arrayVar_.dopeVector[ _i_*4 ], _register_ );					add( @text( _indicies_[_i_] ), _register_ );					#if( array.boundsChk )						#if( @isConst( @text( _indicies_[_i_] ) ))							#if							( 								@text( _indicies_[_i_] ) < 									@dim(_arrayVar_)[_i_]							)								#error( "Constant array index out of bounds" )								#print( "index = ", @text( _indicies_[_i_] ))								#print( "bound = ", @dim(_arrayVar_)[_i_] )							#endif													#else							if							( 								@text( _indicies_[_i_] ) < @dim(_arrayVar_)[_i_]							) then								raise( ex.ArrayBounds );							endif;						#endif					#endif					?_i_:=_i_+1;				#endwhile				?_elementSize_ := 					@Size( @text( @TypeName( _arrayVar_.elementType )));				#if( _elementSize_ = 1 )					// Do nothing				#elseif( _elementSize_ = 2 )					shl( 1, _register_ );				#elseif( _elementSize_ = 4 )					shl( 2, _register_ );				#elseif( _elementSize_ = 8 )					shl( 3, _register_ );				#elseif( _elementSize_ = 16 )					shl( 4, _register_ );				#else									intmul( _elementSize_, _register_ );				#endif				add( _arrayVar_.dataPtr, _register_ );			#endif		#else			// Assume we've got a standard array.			?_numDims_:uns32 := @arity( _arrayVar_ );			#if( _numDims_ <> @elements( _indicies_ ))				#error				( 					@tostring:_arrayVar_ + 					" has " + 					string( _numDims_ ) +					" dimensions, you provided " +					string( @elements( _indicies_ )) +					" dimensions"				);			#else				?_i_ := 1;				mov( @text( _indicies_[0] ), _register_ );				#if( array.boundsChk )					if( _register_ >= @dim(_arrayVar_)[0] ) then						raise( ex.ArrayBounds );					endif;				#endif				#while( _i_ < @arity( _arrayVar_ ))					#if( array.boundsChk )						if( @text( _indicies_[_i_] ) >= @dim(_arrayVar_)[_i_] )						then							raise( ex.ArrayBounds );						endif;					#endif					intmul( @dim(_arrayVar_)[_i_], _register_ );					add( @text( _indicies_[_i_] ), _register_ );					?_i_:=_i_+1;				#endwhile				// Locate the base type of this array.				?_pType_ := @pType( @text( @TypeName( _arrayVar_ )));				?_tempid_ := @TypeName( _arrayVar_ );				#while( _pType_ = hla.ptArray )					?_tempid_ := @typename( @text( _tempid_ ));					?_pType_ := @pType( @text( _tempid_ ));				#endwhile				?_elementSize_ := @Size( @text( _tempid_ ));				#if( _elementSize_ = 1 )					lea( _register_, _arrayVar_[ _register_ ] );				#elseif( _elementSize_ = 2 )					lea( _register_, _arrayVar_[ _register_*2 ] );				#elseif( _elementSize_ = 4 )					lea( _register_, _arrayVar_[ _register_*4 ] );				#elseif( _elementSize_ = 8 )					lea( _register_, _arrayVar_[ _register_*8 ] );				#elseif( _elementSize_ = 16 )					shl( 4, _register_ );					lea( _register_, _arrayVar_[ _register_ ] );				#else									intmul( _elementSize_, _register_ );					lea( _register_, _arrayVar_[ _register_ ] );				#endif			#endif		#endif					#endmacro/*************************************************************************/	// Utility macros used by some of the following routines:	#macro _getArity_( _GAarrayVar_ );		#if( array.isItDynamic( _GAarrayVar_ ))			// Okay, it's a dynamic array.			// The arity is equal to the number of dopeVector elements.			@elements( _GAarrayVar_.dopeVector )		#else			// It's not a dynamic array, just return the arity value.			@arity( _GAarrayVar_ )		#endif	#endmacro	// _copyArray_	//	//	This macro is used by _cpy_ to emit the correct MOVS instruction.	#macro _copyArray_( _elementSize_ );		#if( _elementSize_ = 16 )			shl( 2, ecx );			rep.movsd();		#elseif( _elementSize_ = 8 )			shl( 1, ecx );			rep.movsd();		#elseif( _elementSize_ = 4 )			rep.movsd();		#elseif( _elementSize_ = 2 )			shr( 1, ecx );	// Compute # of dwords.			pushfd();			rep.movsd();			popfd();			if( @c )				movsw();			endif;		#elseif( _elementSize_ = 1 )			rep.movsb();		#else			#if( (_elementSize_ & %11) = 0 )				intmul( _elementSize_ div 4, ecx );				rep.movsd();			#elseif( (_elementSize_ & %1) = 0 )				intmul( _elementSize_ shr 1, ecx );				rep.movsw();			#else				intmul( _elementSize_, ecx );				rep.movsb();			#endif		#endif	#endmacro			// cpy-	//	//	This copies the data in one array to another:	#macro cpy( _src_, _dest_ ):		_aritySrc_,		_arityDest_,		_cpyIndex_,		_cpyElements_,		_srcType_,		_destType_;		#if( @defined( _src_.elementType ))			?_srcType_ := @type( _src_.elementType );		#else			?_srcType_ := @type( _src_ );		#endif		#if( @defined( _dest_.elementType ))			?_destType_ := @type( _dest_.elementType );		#else			?_destType_ := @type( _dest_ );		#endif		?_aritySrc_ := array._getArity_( @text( @string:_src_) );		?_arityDest_ := array._getArity_( @text( @string:_dest_) );		#if( _aritySrc_ <> _arityDest_ )			#error( "The shape and sizes of the two arrays must be the same" );		#elseif( _srcType_ <> _destType_ )			#error( "The base types of the two arrays must be the same" );		#else			// Verify that the two arrays have the same dimensions:			#if( array.isItDynamic( _src_ ) & array.isItDynamic( _dest_ ) )				// Both arrays are dynamic, compare their				// bounds at run-time.								push( ecx );				push( esi );				push( edi );								?_cpyIndex_ := 0;				mov( 1, ecx );				if				(#{									#while( _cpyIndex_ < _aritySrc_ )											mov( _src_.dopeVector[ _cpyIndex_*4 ], edi );						intmul( edi, ecx );						cmp( edi, _dest_.dopeVector[ _cpyIndex_*4 ] );						#if( _cpyIndex_ != _aritySrc_ - 1 )							jne true;						#else							je false;						#endif						?_cpyIndex_ := _cpyIndex_ + 1;					#endwhile									}#) then					raise( ex.ArrayShapeViolation );				endif;				// Emit an appropriate memory move instruction:				cld();				mov( _src_.dataPtr, esi );				mov( _dest_.dataPtr, edi );				array._copyArray_( @size( _src_.elementType ) )				pop( edi );				pop( esi );				pop( ecx );							#elseif			( 					array.isItDynamic( _src_ ) 				&	!array.isItDynamic( _dest_ )			)				// The src array is a dynamic array, the				// dest array is a static array.  Compare				// their bounds at run-time				push( ecx );				push( esi );				push( edi );								?_cpyIndex_ := 0;				?_cpyElements_ := 1;				if				(#{									#while( _cpyIndex_ < _aritySrc_ )											?_cpyElements_ := 							_cpyElements_ * @dim( _dest_ )[ _cpyIndex_ ];						cmp						( 							_src_.dopeVector[ _cpyIndex_*4 ], 							@dim( _dest_ )[ _cpyIndex_ ] 						);						#if( _cpyIndex_ != _aritySrc_ - 1 )							jne true;						#else							je false;						#endif						?_cpyIndex_ := _cpyIndex_ + 1;					#endwhile				}#) then					raise( ex.ArrayShapeViolation );				endif;				// Emit an appropriate memory move instruction:				cld();				mov( _src_.dataPtr, esi );				lea( edi, _dest_ );				mov( _cpyElements_, ecx );				array._copyArray_( @size( _src_.elementType ) )				pop( edi );				pop( esi );				pop( ecx );							#elseif			( 					!array.isItDynamic( _src_ ) 				&	array.isItDynamic( _dest_ )			)			 	// The src array is a static array, the				// dest array is a dynamic array.  Compare				// their bounds at run-time.				push( ecx );				push( esi );				push( edi );								?_cpyIndex_ := 0;				?_cpyElements_ := 1;				if				(#{									#while( _cpyIndex_ < _aritySrc_ )											?_cpyElements_ := 							_cpyElements_ * @dim( _src_ )[ _cpyIndex_ ];						cmp						( 							_dest_.dopeVector[ _cpyIndex_*4 ], 							@dim( _src_ )[ _cpyIndex_ ] 						);						#if( _cpyIndex_ != _aritySrc_ - 1 )							jne true;						#else							je false;						#endif						?_cpyIndex_ := _cpyIndex_ + 1;					#endwhile				}# )then					raise( ex.ArrayShapeViolation );				endif;				// Emit an appropriate memory move instruction:				cld();				mov( _dest_.dataPtr, edi );				lea( esi, _src_ );				mov( _cpyElements_, ecx );				array._copyArray_( @size( _dest_.elementType ) )				pop( edi );				pop( esi );				pop( ecx );			#else				// Both arrays are static arrays.  Compare				// their bounds at compile-time.				push( ecx );				push( esi );				push( edi );								?_cpyIndex_ := 0;				?_cpyElements_ := 1;				#while( _cpyIndex_ < _aritySrc_ )									?_cpyElements_ := 						_cpyElements_ * @dim( _src_ )[ _cpyIndex_ ];					#if					( 							@dim( _src_ )[_cpyIndex_] 						<>  @dim( _dest_ )[_cpyIndex_]					)						#error( "Array shapes must be the same" )					#endif					?_cpyIndex_ := _cpyIndex_ + 1;				#endwhile				// Emit an appropriate memory move instruction:				cld();				lea( edi, _dest_ );				lea( esi, _src_ );				mov( _cpyElements_, ecx );				array._copyArray_( @size( @text( @typename( _src_ ))) )				pop( edi );				pop( esi );				pop( ecx );			#endif		#endif			#endmacro/*************************************************************************/	// reduce-	//	//	This macro does a row reduction.  That is, it eliminates	//	one dimension of the array using a user-defined sequence	//	of instructions.	//	//	Syntax:	//	//		array.reduce( srcArray, destArray )	//	//				<<instrs to perform before reduction>>	//				//			array.beforeRow	//	//				<<instrs to execute before each row is reduced>>	//	//			array.reduction	//	//				<<instrs to perform on each element of the	//					row being reduce.  Note: ESI contains the	//					index into the source array, EAX & EDX are (the	//					only registers) free for use.>>	//	//			array.afterRow	//	//				<<instrs to execute after the row is reduced.	//					Note: EDI contains an index into the	//					destination array.  EAX & EDX are (the only	//					registers) free for use.>>	//	//		array.endreduce;	#macro reduce	( 		_theSrc_, 		_theDest_ 	):			_dimIndex_,			_dimSrc_,			_dimDest_,			_arityDest_,			_aritySrc_,			_goodShape_,			_DidBeforeRow_,			_DidReduce_,			_DidAfterRow_,			_ElementSize_,			_DestElementSize_,			_NumIterations_,			_BadArity_,			_GoodArity_;		?_DidBeforeRow_ := false;		?_DidAfterRow_ := false;		?_DidReduce_ := false;		#if( array.isItDynamic( _theSrc_ ))			?_aritySrc_ := @elements( _theSrc_.dopeVector );			?_ElementSize_ := 	@size								( 									@text( @typename( _theSrc_.elementType ))								);		#else			?_aritySrc_ := @arity( _theSrc_ );			?_ElementSize_ := @size( _theSrc_ ) div @elements( _theSrc_ );		#endif		#if( array.isItDynamic( _theDest_ ))			?_arityDest_ := @elements( _theDest_.dopeVector );			?_DestElementSize_ := 					@size				( 					@text( @typename( _theDest_.elementType ))				);		#else			?_arityDest_ := @arity( _theDest_ );			?_DestElementSize_ := 				@size( _theDest_ ) div @elements( _theDest_ );		#endif		push( ecx );		push( esi );		push( edi );		#if( _ElementSize_ <> _DestElementSize_ )			#error( "Array elements must be the same size" )			?_goodShape_ := false;		#elseif( _aritySrc_ <> _arityDest_ + 1 )			#error			(				"Destination array must have one "				"fewer dimensions than the source array" 			)			?_goodShape_ := false;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -