//------------------------------------------------------------------
//
//  myString.m
//  X-BASIC'
//
//  Created by AIG-Soft(iMac) on 2013/01/31.
//  Copyright (c) 2013年 AIG-Soft. All rights reserved.
//
//------------------------------------------------------------------

#import "myString.h"

//------------------------------------------------------------------

// memcpy()がインライン展開でバグを起こすので回避のため(境界整合を無視してしまう)
void *mmemcpy(void *vdes,void *vsrc,size_t size)
{
	char *des=(char *)vdes;
	char *src=(char *)vsrc;
	while (size-->0) *des++=*src++;
	return (des);
}

// memcpy()がインライン展開でバグを起こすので回避のため(境界整合を無視してしまう)
// sizeが.w単位の時
// vdes/vsrc共に.w境界であること
void *mmemcpyW(void *vdes,void *vsrc,size_t size)
{
	SWord *des=(SWord *)vdes;
	SWord *src=(SWord *)vsrc;
	size/=sizeof(SWord);
	while (size-->0) *des++=*src++;
	return (des);
}

// memcpy()がインライン展開でバグを起こすので回避のため(境界整合を無視してしまう)
// sizeが.l単位の時
// vdes/vsrc共に.w境界であること(ARMは.w境界からの.lアクセスは可能)
void *mmemcpyL(void *vdes,void *vsrc,size_t size)
{
	nslog(@"mmemcpyL(%p,%p,%zu)",vdes,vsrc,size);
	SLong *des=(SLong *)vdes;
	SLong *src=(SLong *)vsrc;
	size/=sizeof(SLong);
	while (size-->0) *des++=*src++;
	return (des);
}

//------------------------------------------------------------------

// void *をポインターへコピー
void *storeVoidPointerToPointer(void *p1,void *p2)
{
	UWord *des=(UWord *)p1;
	UWord *src=(UWord *)p2;
	for (int i=0;i<sizeof(void *)/SZ_WORD;i++) {
		*des++=*src++;
	}
	return des;
}

//------------------------------------------------------------------

// Longをポインター間でコピー
void *copyLongBetweenPointer(void *dl,void *sl)
{
	UWord *des=(UWord *)dl;
	UWord *src=(UWord *)sl;
	// .w*2=.l
	*des++=*src++;
	*des++=*src++;
	return des;
}

// Longをポインターへコピー
void *storeLongToPointer(void *dl,SLong sl)
{
	UWord *des=(UWord *)dl;
	UWord *src=(UWord *)&sl;
	// .w*2=.l
	*des++=*src++;
	*des++=*src++;
	return des;
}

//------------------------------------------------------------------

// DOUBLE_LONGをポインター間でコピー
void *copyDOUBLE_LONGBetweenPointer(DOUBLE_LONG *ddl,DOUBLE_LONG *sdl)
{
	UWord *des=(UWord *)ddl;
	UWord *src=(UWord *)sdl;
	// DOUBLE_LONGは8バイトなのでshort*4
	*des++=*src++;
	*des++=*src++;
	*des++=*src++;
	*des++=*src++;
	return des;
}

// doubleをDOUBLE_LONGポインターへコピー
void *storeDoubleToDOUBLE_LONGPointer(DOUBLE_LONG *ddl,double sd)
{
	// doubleを直接コピーをすると正しくない
	DOUBLE_LONG dl;
	dl.d=sd;
	UWord *des=(UWord *)ddl;
	UWord *src=(UWord *)&dl;
	// DOUBLE_LONGは8バイトなのでshort*4
	*des++=*src++;
	*des++=*src++;
	*des++=*src++;
	*des++=*src++;
	return des;
}

// DOUBLE_LONGポインターからdoubleを読み出す
double readDoubleFromDOUBE_LONGPointer(DOUBLE_LONG *sdl)
{
	double d;
	SWord *des=(SWord *)&d;
	SWord *src=(SWord *)&sdl->d;
	*des++=*src++;
	*des++=*src++;
	*des++=*src++;
	*des++=*src++;
	return (d);
}

//------------------------------------------------------------------

// doubleポインターからdoubleを読み出す
double readDoubleFromDoublePointer(double *dsrc)
{
	double d;
	SWord *des=(SWord *)&d;
	SWord *src=(SWord *)dsrc;
	*des++=*src++;
	*des++=*src++;
	*des++=*src++;
	*des++=*src++;
	return (d);
}

// doubleポインターへdoubleを書き込む
void *storeDoubleToDoublePointer(double *ddes,double d)
{
	SWord *des=(SWord *)ddes;
	SWord *src=(SWord *)&d;
	*des++=*src++;
	*des++=*src++;
	*des++=*src++;
	*des++=*src++;
	return des;
}

//------------------------------------------------------------------

/// ULong値の書き込み
/// @param [in] adrs	書き込みアドレス
/// @param [in] data	書き込みULong値
/// @return 次の書き込みアドレス
void *storeLong(void *adrs,ULong data)
{
	ULong *ladrs=(ULong *)adrs;
#if AARM>=2
	copyLongBetweenPointer(ladrs, &data);
#else
	*(ULong *)ladrs=data;
#endif
	return ++ladrs;
}

/// ULong値の読み出し
/// @param [in] adrs	読み込みアドレス
/// @return 読み出した値
ULong readLong(void *adrs)
{
	ULong *ladrs=(ULong *)adrs;
	ULong num;
#if AARM>=2
	copyLongBetweenPointer(&num,ladrs);
#else
	num=*ladrs;
#endif
	return num;
}


/// DOUBLE_LONG値の読み出し
/// @param [in/out] dl		読みだした値を入れるアドレス
/// @param [in] 	adrs	読み込みアドレス
void readDOUBLE_LONG(DOUBLE_LONG *dl,void *adrs)
{
	DOUBLE_LONG *ladrs=(DOUBLE_LONG *)adrs;
#if AARM>=1
	copyDOUBLE_LONGBetweenPointer(dl,ladrs);
#else
	*dl=*ladrs;
#endif
}

/// double値の読み出し
/// @param [in] adrs	元アドレス
/// @param [in] dp		&double(書き込み先アドレス)
double readDouble(void *adrs)
{
	double d;
	char *p =(char *)adrs;
	char *bp=(char *)&d;
	for (int i=0;i<sizeof(double);i++) {
		*bp++=*p++;
	}
	return d;
}

//--------------------------------------------------------------------------------------
