/*
** HDL4SE: 软件Verilog综合仿真平台
** Copyright (C) 2021-2021, raoxianhong<raoxianhong@163.net>
** LCOM: 轻量级组件对象模型
** Copyright (C) 2021-2021, raoxianhong<raoxianhong@163.net>
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice,
**   this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
**   this list of conditions and the following disclaimer in the documentation
**   and/or other materials provided with the distribution.
** * The name of the author may be used to endorse or promote products
**   derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
** THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
* bignumber.h
    202105201110: rxh, initial version
*/

#ifndef __BIGNUMBER_H
#define __BIGNUMBER_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef _ASMLANGUAGE

#include "guid.h"

DEFINE_GUID(IID_BIGNUMBER, 0x80dc5305, 0x1ca6, 0x4678, 0xbf, 0xc3, 0xd0, 0x1b, 0x9c, 0xd3, 0x63, 0x62);

typedef struct sIBigNumber {
    OBJECT_INTERFACE
    int (*GetWidth)(HOBJECT object);
    int (*SetWidth)(HOBJECT object, int width, int signexpand);
    
    int (*GetBits32)(HOBJECT object, int ind32, unsigned int* pbits);
    int (*SetBits32)(HOBJECT object, int ind32, unsigned int bits);

    int (*GetBit)(HOBJECT object, int indbit);
    int (*SetBit)(HOBJECT object, int indbit, int bit);

    int (*GetInt32)(HOBJECT object, int* pvalue);
    int (*GetInt64)(HOBJECT object, long long* pvalue);
    int (*GetUint32)(HOBJECT object, unsigned int* pvalue);
    int (*GetUint64)(HOBJECT object, unsigned long long* pvalue);

    int (*GetStr)(HOBJECT object, int base, char * str, int buflen);

    int (*AssignInt32)(HOBJECT object, int value);
    int (*AssignInt64)(HOBJECT object, long long value);
    int (*AssignUint32)(HOBJECT object, unsigned int value);
    int (*AssignUint64)(HOBJECT object, unsigned long long value);

    int (*AssignStr)(HOBJECT object, const char* str, const char** nstr, int autowidth);

    int (*Clone)(HOBJECT object, HOBJECT src);
    int (*CloneSubBits)(HOBJECT object, HOBJECT src, int from, int width, int signexpand);
    int (*Assign)(HOBJECT object, HOBJECT src);
    int (*AssignSubBits)(HOBJECT object, HOBJECT src, int from, int width);
    int (*AssignU)(HOBJECT object, HOBJECT src);
    int (*AssignSubBitsU)(HOBJECT object, HOBJECT src, int from, int width);

    int (*AddInt32)(HOBJECT object, HOBJECT src, int value);
    int (*SubInt32)(HOBJECT object, HOBJECT src, int value);
    int (*MulInt32)(HOBJECT object, HOBJECT src, int value);
    int (*DivInt32)(HOBJECT object, HOBJECT src, int value);
    int (*ModInt32)(HOBJECT object, HOBJECT src, int value);

    int (*AddUint32)(HOBJECT object, HOBJECT src, unsigned int value);
    int (*SubUint32)(HOBJECT object, HOBJECT src, unsigned int value);
    int (*MulUint32)(HOBJECT object, HOBJECT src, unsigned int value);
    int (*DivUint32)(HOBJECT object, HOBJECT src, unsigned int value);
    int (*ModUint32)(HOBJECT object, HOBJECT src, unsigned int value);

    int (*Add)(HOBJECT object, HOBJECT src0, HOBJECT src1);
    int (*Sub)(HOBJECT object, HOBJECT src0, HOBJECT src1);
    int (*Mul)(HOBJECT object, HOBJECT src0, HOBJECT src1);
    int (*Div)(HOBJECT object, HOBJECT src0, HOBJECT src1);
    int (*Mod)(HOBJECT object, HOBJECT src0, HOBJECT src1);

    int (*AddU)(HOBJECT object, HOBJECT src0, HOBJECT src1);
    int (*SubU)(HOBJECT object, HOBJECT src0, HOBJECT src1);
    int (*MulU)(HOBJECT object, HOBJECT src0, HOBJECT src1);
    int (*DivU)(HOBJECT object, HOBJECT src0, HOBJECT src1);
    int (*ModU)(HOBJECT object, HOBJECT src0, HOBJECT src1);

    int (*Neg)(HOBJECT object, HOBJECT src);
    int (*Abs)(HOBJECT object, HOBJECT src);

    int (*IsGT)(HOBJECT object, HOBJECT src);
    int (*IsGE)(HOBJECT object, HOBJECT src);
    int (*IsLT)(HOBJECT object, HOBJECT src);
    int (*IsLE)(HOBJECT object, HOBJECT src);
    int (*IsEQ)(HOBJECT object, HOBJECT src);
    int (*IsNE)(HOBJECT object, HOBJECT src);

    int (*IsGTU)(HOBJECT object, HOBJECT src);
    int (*IsGEU)(HOBJECT object, HOBJECT src);
    int (*IsLTU)(HOBJECT object, HOBJECT src);
    int (*IsLEU)(HOBJECT object, HOBJECT src);
    int (*IsEQU)(HOBJECT object, HOBJECT src);
    int (*IsNEU)(HOBJECT object, HOBJECT src);

    int (*IsZero)(HOBJECT object);
    int (*IsNotZero)(HOBJECT object);
    int (*IsNeg)(HOBJECT object);

    int (*AndL)(HOBJECT object, HOBJECT src);
    int (*OrL)(HOBJECT object, HOBJECT src);
    int (*NotL)(HOBJECT object);

    int (*And)(HOBJECT object, HOBJECT src0, HOBJECT src1);
    int (*Or)(HOBJECT object, HOBJECT src0, HOBJECT src1);
    int (*Xor)(HOBJECT object, HOBJECT src0, HOBJECT src1);
    int (*Not)(HOBJECT object, HOBJECT src);

    int (*uAnd)(HOBJECT object, HOBJECT src);
    int (*uAndNot)(HOBJECT object, HOBJECT src);
    int (*uOr)(HOBJECT object, HOBJECT src);
    int (*uOrNot)(HOBJECT object, HOBJECT src);
    int (*uXor)(HOBJECT object, HOBJECT src);
    int (*uXorNot)(HOBJECT object, HOBJECT src);

    int (*SHL)(HOBJECT object, HOBJECT src, int bits);
    int (*SHR)(HOBJECT object, HOBJECT src, int bits);
    int (*SAL)(HOBJECT object, HOBJECT src, int bits);
    int (*SAR)(HOBJECT object, HOBJECT src, int bits);

}IBigNumber;

#define BIGNUMBER_VARDECLARE
#define BIGNUMBER_VARINIT(_objptr, _sid)

#define BIGNUMBER_FUNCDECLARE(_obj, _clsid, _localstruct) \
    static int _obj##_bn_GetWidth(HOBJECT object); \
    static int _obj##_bn_SetWidth(HOBJECT object, int width, int signexpand); \
    static int _obj##_bn_GetBits32(HOBJECT object, int ind32, unsigned int* pbits); \
    static int _obj##_bn_SetBits32(HOBJECT object, int ind32, unsigned int bits); \
    static int _obj##_bn_GetBit(HOBJECT object, int indbit); \
    static int _obj##_bn_SetBit(HOBJECT object, int indbit, int bit); \
    static int _obj##_bn_GetInt32(HOBJECT object, int* pvalue); \
    static int _obj##_bn_GetInt64(HOBJECT object, long long* pvalue); \
    static int _obj##_bn_GetUint32(HOBJECT object, unsigned int* pvalue); \
    static int _obj##_bn_GetUint64(HOBJECT object, unsigned long long* pvalue); \
    static int _obj##_bn_GetStr(HOBJECT object, int base, char* str, int buflen); \
    static int _obj##_bn_AssignInt32(HOBJECT object, int value); \
    static int _obj##_bn_AssignInt64(HOBJECT object, long long value); \
    static int _obj##_bn_AssignUint32(HOBJECT object, unsigned int value); \
    static int _obj##_bn_AssignUint64(HOBJECT object, unsigned long long value); \
    static int _obj##_bn_AssignStr(HOBJECT object, const char* str, const char** nstr, int autowidth); \
    static int _obj##_bn_Clone(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_CloneSubBits(HOBJECT object, HOBJECT src, int from, int width, int signexpand); \
    static int _obj##_bn_Assign(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_AssignSubBits(HOBJECT object, HOBJECT src, int from, int width); \
    static int _obj##_bn_AssignU(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_AssignSubBitsU(HOBJECT object, HOBJECT src, int from, int width); \
    static int _obj##_bn_AddInt32(HOBJECT object, HOBJECT src, int value); \
    static int _obj##_bn_SubInt32(HOBJECT object, HOBJECT src, int value); \
    static int _obj##_bn_MulInt32(HOBJECT object, HOBJECT src, int value); \
    static int _obj##_bn_DivInt32(HOBJECT object, HOBJECT src, int value); \
    static int _obj##_bn_ModInt32(HOBJECT object, HOBJECT src, int value); \
    static int _obj##_bn_AddUint32(HOBJECT object, HOBJECT src, unsigned int value); \
    static int _obj##_bn_SubUint32(HOBJECT object, HOBJECT src, unsigned int value); \
    static int _obj##_bn_MulUint32(HOBJECT object, HOBJECT src, unsigned int value); \
    static int _obj##_bn_DivUint32(HOBJECT object, HOBJECT src, unsigned int value); \
    static int _obj##_bn_ModUint32(HOBJECT object, HOBJECT src, unsigned int value); \
    static int _obj##_bn_Add(HOBJECT object, HOBJECT src0, HOBJECT src1); \
    static int _obj##_bn_Sub(HOBJECT object, HOBJECT src0, HOBJECT src1); \
    static int _obj##_bn_Mul(HOBJECT object, HOBJECT src0, HOBJECT src1); \
    static int _obj##_bn_Div(HOBJECT object, HOBJECT src0, HOBJECT src1); \
    static int _obj##_bn_Mod(HOBJECT object, HOBJECT src0, HOBJECT src1); \
    static int _obj##_bn_AddU(HOBJECT object, HOBJECT src0, HOBJECT src1); \
    static int _obj##_bn_SubU(HOBJECT object, HOBJECT src0, HOBJECT src1); \
    static int _obj##_bn_MulU(HOBJECT object, HOBJECT src0, HOBJECT src1); \
    static int _obj##_bn_DivU(HOBJECT object, HOBJECT src0, HOBJECT src1); \
    static int _obj##_bn_ModU(HOBJECT object, HOBJECT src0, HOBJECT src1); \
    static int _obj##_bn_Neg(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_Abs(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_IsGT(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_IsGE(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_IsLT(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_IsLE(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_IsEQ(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_IsNE(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_IsGTU(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_IsGEU(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_IsLTU(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_IsLEU(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_IsEQU(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_IsNEU(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_IsZero(HOBJECT object); \
    static int _obj##_bn_IsNotZero(HOBJECT object); \
    static int _obj##_bn_IsNeg(HOBJECT object); \
    static int _obj##_bn_AndL(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_OrL(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_NotL(HOBJECT object); \
    static int _obj##_bn_And(HOBJECT object, HOBJECT src0, HOBJECT src1); \
    static int _obj##_bn_Or(HOBJECT object, HOBJECT src0, HOBJECT src1); \
    static int _obj##_bn_Xor(HOBJECT object, HOBJECT src0, HOBJECT src1); \
    static int _obj##_bn_Not(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_uAnd(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_uAndNot(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_uOr(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_uOrNot(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_uXor(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_uXorNot(HOBJECT object, HOBJECT src); \
    static int _obj##_bn_SHL(HOBJECT object, HOBJECT src, int bits); \
    static int _obj##_bn_SHR(HOBJECT object, HOBJECT src, int bits); \
    static int _obj##_bn_SAL(HOBJECT object, HOBJECT src, int bits); \
    static int _obj##_bn_SAR(HOBJECT object, HOBJECT src, int bits); \
static const IBigNumber _obj##_bn_interface = { \
   	INTERFACE_HEADER(_obj, IBigNumber, _localstruct) \
        _obj##_bn_GetWidth, \
        _obj##_bn_SetWidth, \
        _obj##_bn_GetBits32, \
        _obj##_bn_SetBits32, \
        _obj##_bn_GetBit, \
        _obj##_bn_SetBit, \
       _obj##_bn_GetInt32, \
        _obj##_bn_GetInt64, \
        _obj##_bn_GetUint32, \
        _obj##_bn_GetUint64, \
        _obj##_bn_GetStr, \
        _obj##_bn_AssignInt32, \
        _obj##_bn_AssignInt64, \
        _obj##_bn_AssignUint32, \
        _obj##_bn_AssignUint64, \
        _obj##_bn_AssignStr, \
        _obj##_bn_Clone, \
        _obj##_bn_CloneSubBits, \
        _obj##_bn_Assign, \
        _obj##_bn_AssignSubBits, \
        _obj##_bn_AssignU, \
        _obj##_bn_AssignSubBitsU, \
        _obj##_bn_AddInt32, \
        _obj##_bn_SubInt32, \
        _obj##_bn_MulInt32, \
        _obj##_bn_DivInt32, \
        _obj##_bn_ModInt32, \
        _obj##_bn_AddUint32, \
        _obj##_bn_SubUint32, \
        _obj##_bn_MulUint32, \
        _obj##_bn_DivUint32, \
        _obj##_bn_ModUint32, \
        _obj##_bn_Add, \
        _obj##_bn_Sub, \
        _obj##_bn_Mul, \
        _obj##_bn_Div, \
        _obj##_bn_Mod, \
        _obj##_bn_AddU, \
        _obj##_bn_SubU, \
        _obj##_bn_MulU, \
        _obj##_bn_DivU, \
        _obj##_bn_ModU, \
        _obj##_bn_Neg, \
        _obj##_bn_Abs, \
        _obj##_bn_IsGT, \
        _obj##_bn_IsGE, \
        _obj##_bn_IsLT, \
        _obj##_bn_IsLE, \
        _obj##_bn_IsEQ, \
        _obj##_bn_IsNE, \
        _obj##_bn_IsGTU, \
        _obj##_bn_IsGEU, \
        _obj##_bn_IsLTU, \
        _obj##_bn_IsLEU, \
        _obj##_bn_IsEQU, \
        _obj##_bn_IsNEU, \
        _obj##_bn_IsZero, \
        _obj##_bn_IsNotZero, \
        _obj##_bn_IsNeg, \
        _obj##_bn_AndL, \
        _obj##_bn_OrL, \
        _obj##_bn_NotL, \
        _obj##_bn_And, \
        _obj##_bn_Or, \
        _obj##_bn_Xor, \
        _obj##_bn_Not, \
        _obj##_bn_uAnd, \
        _obj##_bn_uAndNot, \
        _obj##_bn_uOr, \
        _obj##_bn_uOrNot, \
        _obj##_bn_uXor, \
        _obj##_bn_uXorNot, \
        _obj##_bn_SHL, \
        _obj##_bn_SHR, \
        _obj##_bn_SAL, \
        _obj##_bn_SAR, \
    };


DEFINE_GUID(CLSID_BIGINTEGER, 0xabde0235, 0x8f00, 0x4f30, 0x92, 0xbf, 0x95, 0x2e, 0x35, 0x8b, 0x1a, 0xeb);
DEFINE_GUID(PARAMID_BIGINTEGERWIDTH, 0xb3a21034, 0x27d5, 0x4e09, 0xba, 0xfd, 0x2, 0xeb, 0x0, 0xfc, 0x28, 0xfb);

IBigNumber** bigintegerCreate(int width);

#endif /* _ASMLANGUAGE */

#ifdef __cplusplus
}
#endif

#endif /* __BIGNUMBER_H */