Goose  Artifact [a5f457cef4]

Artifact a5f457cef4edb8e00947e23b8003f7911c968adcfd5fd53a2a9b9e9b3305d130:

  • File bs/builtins/types/runtime/basic.cpp — part of check-in [0db147f117] at 2024-09-15 20:24:31 on branch cir-ssa-refactor — Add clang format settings, reformat everything (user: achavasse size: 7068)

#include "builtins/builtins.h"
#include "codegen/codegen.h"

using namespace goose;
using namespace goose::builtins;
using namespace goose::codegen;

namespace goose::builtins
{
    void SetupRuntimeBasicTypes( Env& e )
    {
        DefineConstant( e, "half"_sid, ValueToEIR( ToValue( HalfFloatType() ) ) );
        DefineConstant( e, "float"_sid, ValueToEIR( ToValue( FloatType() ) ) );
        DefineConstant( e, "double"_sid, ValueToEIR( ToValue( DoubleFloatType() ) ) );

        RegisterBuiltinFunc< Eager< Value >( uint32_t ) >(
            e, "uint"_sid, []( uint32_t numBits ) { return ToValue( IntegerType( numBits ) ); } );

        RegisterBuiltinFunc< Eager< Value >( uint32_t ) >( e, "sint"_sid,
            []( uint32_t numBits ) { return ToValue( IntegerType( numBits, true ) ); } );
    }

    const Term& IntegerType::Pattern::GetPattern()
    {
        static auto pattern = ValueToEIR( Value( TypeType(),
            MkStdRTType( TSID( rt_type ), nullptr, TSID( integer ),
                VEC( HOLE( "size"_sid ), HOLE( "signedness"_sid ) ) ) ) );

        return pattern;
    }

    const Term& IntegerType::PatternSigned::GetPattern()
    {
        static auto pattern = ValueToEIR( Value( TypeType(),
            MkStdRTType( TSID( rt_type ), nullptr, TSID( integer ),
                VEC( HOLE( "size"_sid ), TERM( 1U ) ) ) ) );

        return pattern;
    }

    const Term& IntegerType::PatternUnsigned::GetPattern()
    {
        static auto pattern = ValueToEIR( Value( TypeType(),
            MkStdRTType( TSID( rt_type ), nullptr, TSID( integer ),
                VEC( HOLE( "size"_sid ), TERM( 0U ) ) ) ) );

        return pattern;
    }

    const Term& IntegerType::PatternUnsigned32::GetPattern()
    {
        static auto pattern = ValueToEIR( Value( TypeType(),
            MkStdRTType(
                TSID( rt_type ), nullptr, TSID( integer ), VEC( TERM( 32U ), TERM( 0U ) ) ) ) );

        return pattern;
    }

    const codegen::Type* GetCodegenType( const HalfFloatType& t )
    {
        // TODO_SSA reenable
        return nullptr; // codegen::Type::Get( llvm::Type::getHalfTy( GetLLVMContext() ) );
    }

    const codegen::Type* GetCodegenType( const FloatType& t )
    {
        // TODO_SSA reenable
        return nullptr; // codegen::Type::Get( llvm::Type::getFloatTy( GetLLVMContext() ) );
    }

    const codegen::Type* GetCodegenType( const DoubleFloatType& t )
    {
        // TODO_SSA reenable
        return nullptr; // codegen::Type::Get( llvm::Type::getDoubleTy( GetLLVMContext() ) );
    }

    const codegen::Type* GetCodegenType( const IntegerType& t )
    {
        // TODO_SSA reenable
        return nullptr; // codegen::Type::Get( llvm::IntegerType::get( GetLLVMContext(), t.m_numBits
                        // ) );
    }
} // namespace goose::builtins

namespace goose::eir
{
    //// Half
    Value Bridge< HalfFloatType >::ToValue( const HalfFloatType& t )
    {
        return Value( Type(), MkStdRTType( TSID( rt_type ), GetCodegenType( t ), TSID( half ) ) );
    }

    optional< HalfFloatType > Bridge< HalfFloatType >::FromValue( const Value& v )
    {
        if( v != ToValue( HalfFloatType() ) )
            return nullopt;

        return {};
    }

    //// Float
    Value Bridge< FloatType >::ToValue( const FloatType& t )
    {
        return Value( Type(), MkStdRTType( TSID( rt_type ), GetCodegenType( t ), TSID( float ) ) );
    }

    optional< FloatType > Bridge< FloatType >::FromValue( const Value& v )
    {
        if( v != ToValue( FloatType() ) )
            return nullopt;

        return {};
    }

    //// Double
    Value Bridge< DoubleFloatType >::ToValue( const DoubleFloatType& t )
    {
        return Value( Type(), MkStdRTType( TSID( rt_type ), GetCodegenType( t ), TSID( double ) ) );
    }

    optional< DoubleFloatType > Bridge< DoubleFloatType >::FromValue( const Value& v )
    {
        if( v != ToValue( DoubleFloatType() ) )
            return nullopt;

        return {};
    }

    //// Integer
    Value Bridge< IntegerType >::ToValue( const IntegerType& t )
    {
        return Value( Type(),
            MkStdRTType( TSID( rt_type ), GetCodegenType( t ), TSID( integer ),
                VEC( TERM( t.m_numBits ), t.m_signed ? TERM( 1U ) : TERM( 0U ) ) ) );
    }

    optional< IntegerType > Bridge< IntegerType >::FromValue( const Value& v )
    {
        auto result = Decompose( v.val(),
            Vec( Lit( "rt_type"_sid ), SubTerm(), Val< void* >(), Lit( "integer"_sid ),
                Vec( Val< uint64_t >(), Val< uint64_t >() ) ) );

        if( !result )
            return nullopt;

        auto&& [predicates, cgType, params] = *result;
        auto&& [numBits, signd] = params;
        return IntegerType( numBits, !!signd );
    }

    Term Bridge< APSInt >::Type( const APSInt& i )
    {
        return ValueToEIR( eir::ToValue( IntegerType( i.getBitWidth(), i.isSigned() ) ) );
    }

    Value Bridge< APSInt >::ToValue( const APSInt& i )
    {
        return Value( Type( i ), TERM( i ) );
    }

    optional< APSInt > Bridge< APSInt >::FromValue( const Value& v )
    {
        auto result = Decompose( v.val(), Val< APSInt >() );

        if( !result )
            return nullopt;

        return *result;
    }

    const Term& Bridge< uint8_t >::Type()
    {
        static auto type = ValueToEIR( eir::ToValue( IntegerType( 8, false ) ) );
        return type;
    }

    Value Bridge< uint8_t >::ToValue( uint8_t x )
    {
        return eir::ToValue( APSInt::getUnsigned( x ).trunc( 8 ) );
    }

    optional< uint8_t > Bridge< uint8_t >::FromValue( const Value& v )
    {
        return FromValue< APSInt >( v )->getLimitedValue();
    }

    const Term& Bridge< uint32_t >::Type()
    {
        static auto type = ValueToEIR( eir::ToValue( IntegerType( 32, false ) ) );
        return type;
    }

    Value Bridge< uint32_t >::ToValue( uint32_t x )
    {
        return eir::ToValue( APSInt::getUnsigned( x ).trunc( 32 ) );
    }

    optional< uint32_t > Bridge< uint32_t >::FromValue( const Value& v )
    {
        return FromValue< APSInt >( v )->getLimitedValue();
    }

    const Term& Bridge< int32_t >::Type()
    {
        static auto type = ValueToEIR( eir::ToValue( IntegerType( 32, true ) ) );
        return type;
    }

    Value Bridge< int32_t >::ToValue( int32_t x )
    {
        return eir::ToValue( APSInt::get( x ).trunc( 32 ) );
    }

    optional< int32_t > Bridge< int32_t >::FromValue( const Value& v )
    {
        return FromValue< APSInt >( v )->getExtValue();
    }

    const Term& Bridge< uint64_t >::Type()
    {
        static auto type = ValueToEIR( eir::ToValue( IntegerType( 64, false ) ) );
        return type;
    }

    Value Bridge< uint64_t >::ToValue( uint64_t x )
    {
        return eir::ToValue( APSInt::getUnsigned( x ) );
    }

    optional< uint64_t > Bridge< uint64_t >::FromValue( const Value& v )
    {
        if( !v.isConstant() )
            return nullopt;
        return FromValue< APSInt >( v )->getLimitedValue();
    }
} // namespace goose::eir