-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
549 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,8 +43,8 @@ CPPFLAGS = -I../src -I../driver -MD -MF [email protected] | |
|
||
OBJS_com = \ | ||
fixed64.o ieee_float.o float80_base.o float80_hard.o float80_soft.o \ | ||
dec_float.o str_buffer.o str_scanner.o option_base.o error_reporter.o \ | ||
insn_base.o formatters.o value_formatter.o \ | ||
dec_float.o ibm_float.o str_buffer.o str_scanner.o option_base.o \ | ||
error_reporter.o insn_base.o formatters.o value_formatter.o \ | ||
$(foreach a,$(ARCHS),$(OBJS_$(a))) \ | ||
bin_memory.o bin_decoder.o bin_encoder.o intel_hex.o moto_srec.o \ | ||
file_reader.o file_printer.o list_formatter.o text_common.o | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
/* | ||
* Copyright 2024 Tadashi G. Takaoka | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include "ibm_float.h" | ||
#include "fixed64.h" | ||
#include "str_buffer.h" | ||
|
||
namespace libasm { | ||
|
||
const char *__ibm_float32::str() const { | ||
static char buf[16]; | ||
StrBuffer out{buf, sizeof(buf)}; | ||
const auto sig = _u32 & SIG_MASK; | ||
out.hex(tag(), 2).letter('.').hex(sig, 6); | ||
return buf; | ||
} | ||
|
||
__ibm_float32 &__ibm_float32::set(uint8_t tag, uint32_t sig) { | ||
return set((static_cast<uint32_t>(tag) << TAG_POS) | (sig & SIG_MASK)); | ||
} | ||
|
||
__ibm_float32 &__ibm_float32::set(uint32_t bits) { | ||
_u32 = bits; | ||
return *this; | ||
} | ||
|
||
Error __ibm_float32::set(const float80_t &f80) { | ||
auto error = OK; | ||
if (f80.isNan()) | ||
error = NOT_AN_EXPECTED; | ||
if (f80.isInf()) | ||
error = OVERFLOW_RANGE; | ||
if (f80.isZero() || error) { | ||
_u32 = bits(f80.isNegative(), 0, 0); | ||
return error; | ||
} | ||
fixed64_t sig; | ||
// IBM float fraction is [1/16 .. 1.0) | ||
// IEEE float fraction is [1.0 .. 2.0) | ||
auto ieee_exp = f80.decompose(sig) + 1; // +1 for adjust | ||
ieee_exp += sig.normalize(); | ||
while (ieee_exp % 4) { | ||
ieee_exp++; | ||
sig.shift_right(1); | ||
} | ||
sig.round_off(MANT_DIG); | ||
auto ibm_exp = ieee_exp / 4; | ||
auto ibm_sig = sig.value() >> (64 - TAG_POS); // has explicit MSB | ||
if (ibm_exp >= EXP_BASE) { | ||
error = OVERFLOW_RANGE; | ||
ibm_exp = -EXP_BASE; // ibm_sig = 0 | ||
} | ||
if (ibm_exp < -EXP_BASE) { | ||
ibm_exp = -EXP_BASE; | ||
ibm_sig = 0; | ||
} | ||
_u32 = bits(f80.isNegative(), ibm_exp + EXP_BASE, ibm_sig); | ||
return error; | ||
} | ||
|
||
uint32_t __ibm_float32::bits(bool sign, uint8_t exp, uint32_t sig) { | ||
const auto tag = (sign ? SGN_MASK : 0) | exp; | ||
return (static_cast<uint32_t>(tag) << TAG_POS) | (sig & SIG_MASK); | ||
} | ||
|
||
__ibm_float32::operator float80_t() const { | ||
const auto tag = static_cast<uint16_t>(_u32 >> TAG_POS); | ||
const auto sign = (tag & SGN_MASK) != 0; | ||
const auto bexp = tag & EXP_MASK; | ||
const auto ibm_exp = static_cast<int16_t>(bexp) - EXP_BASE; | ||
const auto ibm_sig = (_u32 & SIG_MASK); | ||
if (bexp == 0 && ibm_sig == 0) | ||
return float80_t::zero(sign); | ||
fixed64_t ieee_sig{static_cast<uint64_t>(ibm_sig) << (64 - MANT_DIG)}; | ||
// IBM float fraction is [1/16 .. 1.0) | ||
// IEEE float fraction is [1.0 .. 2.0) | ||
auto ieee_exp = ibm_exp * 4 - 1; // -1 for adjust | ||
ieee_exp += ieee_sig.normalize(); | ||
return float80_t::compose(sign, ieee_exp, ieee_sig); | ||
} | ||
|
||
const char *__ibm_float64::str() const { | ||
static char buf[20]; | ||
StrBuffer out{buf, sizeof(buf)}; | ||
const auto sig = _u64 & SIG_MASK; | ||
out.hex(tag(), 2) | ||
.letter('.') | ||
.hex(static_cast<uint32_t>(sig >> 32), 6) | ||
.letter('-') | ||
.hex(static_cast<uint32_t>(sig), 8); | ||
return buf; | ||
} | ||
|
||
__ibm_float64 &__ibm_float64::set(uint8_t tag, uint64_t sig) { | ||
return set((static_cast<uint64_t>(tag) << TAG_POS) | (sig & SIG_MASK)); | ||
} | ||
|
||
__ibm_float64 &__ibm_float64::set(uint64_t bits) { | ||
_u64 = bits; | ||
return *this; | ||
} | ||
|
||
Error __ibm_float64::set(const float80_t &f80) { | ||
auto error = OK; | ||
if (f80.isNan()) | ||
error = NOT_AN_EXPECTED; | ||
if (f80.isInf()) | ||
error = OVERFLOW_RANGE; | ||
if (f80.isZero() || error) { | ||
_u64 = bits(f80.isNegative(), 0, 0); | ||
return error; | ||
} | ||
fixed64_t sig; | ||
// IBM float fraction is [1/16 .. 1.0) | ||
// IEEE float fraction is [1.0 .. 2.0) | ||
auto ieee_exp = f80.decompose(sig) + 1; // +1 for adjust | ||
while (ieee_exp % 4) { | ||
ieee_exp++; | ||
sig.shift_right(1); | ||
} | ||
sig.round_off(MANT_DIG); | ||
auto ibm_exp = ieee_exp / 4; | ||
auto ibm_sig = sig.value() >> (64 - TAG_POS); // has explicit MSB | ||
if (ibm_exp >= EXP_BASE) { | ||
error = OVERFLOW_RANGE; | ||
ibm_exp = -EXP_BASE; // ibm_sig = 0 | ||
} | ||
if (ibm_exp < -EXP_BASE) { | ||
ibm_exp = -EXP_BASE; | ||
ibm_sig = 0; | ||
} | ||
_u64 = bits(f80.isNegative(), ibm_exp + EXP_BASE, ibm_sig); | ||
return error; | ||
} | ||
|
||
uint64_t __ibm_float64::bits(bool sign, uint8_t exp, uint64_t sig) { | ||
const auto tag = (sign ? SGN_MASK : 0) | exp; | ||
return (static_cast<uint64_t>(tag) << TAG_POS) | (sig & SIG_MASK); | ||
} | ||
|
||
__ibm_float64::operator float80_t() const { | ||
const auto tag = static_cast<uint16_t>(_u64 >> TAG_POS); | ||
const auto sign = (tag & SGN_MASK) != 0; | ||
const auto bexp = tag & EXP_MASK; | ||
const auto ibm_exp = static_cast<int16_t>(bexp) - EXP_BASE; | ||
const auto ibm_sig = (_u64 & SIG_MASK); | ||
if (bexp == 0 && ibm_sig == 0) | ||
return float80_t::zero(sign); | ||
fixed64_t ieee_sig{static_cast<uint64_t>(ibm_sig) << (64 - MANT_DIG)}; | ||
// IBM float fraction is [1/16 .. 1.0) | ||
// IEEE float fraction is [1.0 .. 2.0) | ||
auto ieee_exp = ibm_exp * 4 - 1; // -1 for adjust | ||
ieee_exp += ieee_sig.normalize(); | ||
return float80_t::compose(sign, ieee_exp, ieee_sig); | ||
} | ||
|
||
} // namespace libasm | ||
|
||
// Local Variables: | ||
// mode: c++ | ||
// c-basic-offset: 4 | ||
// tab-width: 4 | ||
// End: | ||
// vim: set ft=cpp et ts=4 sw=4: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* | ||
* Copyright 2024 Tadashi G. Takaoka | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef __LIBASM_IBM_FLOAT_H__ | ||
#define __LIBASM_IBM_FLOAT_H__ | ||
|
||
#include <stdint.h> | ||
#include "error_reporter.h" | ||
#include "float80.h" | ||
|
||
#define IBMF32_MAX 7.237005e+75 | ||
#define IBMF32_MIN 5.397605e-79 | ||
#define IBMF64_MAX 7.237005577332262114e+75 | ||
#define IBMF64_MIN 5.397605346934027891e-79 | ||
|
||
namespace libasm { | ||
|
||
struct __ibm_float32 { | ||
__ibm_float32(uint8_t tag = 0, uint32_t sig = 0) { set(tag, sig); } | ||
__ibm_float32(const __ibm_float32 &f32) = default; | ||
__ibm_float32 &operator=(const __ibm_float32 &f32) = default; | ||
|
||
__ibm_float32 &set(uint8_t tag, uint32_t sig); | ||
__ibm_float32 &set(uint32_t bits); | ||
|
||
Error set(const float80_t &f80); | ||
explicit operator float80_t() const; | ||
|
||
uint32_t bits() const { return _u32; } | ||
uint8_t tag() const { return _u32 >> TAG_POS; } | ||
static uint32_t bits(bool sign, uint8_t exp, uint32_t sig); | ||
|
||
const char *str() const; | ||
|
||
static constexpr auto MANT_DIG = 24; | ||
static constexpr auto TAG_POS = MANT_DIG; | ||
static constexpr auto SGN_MASK = UINT8_C(0x80); | ||
static constexpr auto EXP_MASK = UINT8_C(0x7F); | ||
static constexpr auto EXP_BASE = INT8_C(0x40); | ||
static constexpr auto SIG_MASK = (UINT32_C(1) << TAG_POS) - 1; | ||
static constexpr auto MSD_POS = MANT_DIG - 4; | ||
|
||
private: | ||
// |sign| bexp(7) | frac(24) | | ||
// sign: 1=negative | ||
// bexp: biased radix 16 exponent, offset 0x40, 0=zero | ||
// frac: fraction hexadecimal digits, 1/16 <= frac < 1 | ||
uint32_t _u32; | ||
}; | ||
|
||
struct __ibm_float64 { | ||
__ibm_float64(uint8_t tag = 0, uint64_t sig = 0) { set(tag, sig); } | ||
__ibm_float64(const __ibm_float64 &f64) = default; | ||
__ibm_float64 &operator=(const __ibm_float64 &f64) = default; | ||
|
||
__ibm_float64 &set(uint8_t tag, uint64_t sig); | ||
__ibm_float64 &set(uint64_t bits); | ||
|
||
Error set(const float80_t &f80); | ||
explicit operator float80_t() const; | ||
|
||
uint64_t bits() const { return _u64; } | ||
uint8_t tag() const { return _u64 >> TAG_POS; } | ||
static uint64_t bits(bool sign, uint8_t exp, uint64_t sig); | ||
|
||
const char *str() const; | ||
|
||
static constexpr auto MANT_DIG = 56; | ||
static constexpr auto TAG_POS = MANT_DIG; | ||
static constexpr auto SGN_MASK = UINT8_C(0x80); | ||
static constexpr auto EXP_MASK = UINT8_C(0x7F); | ||
static constexpr auto EXP_BASE = INT8_C(0x40); | ||
static constexpr auto SIG_MASK = (UINT64_C(1) << TAG_POS) - 1; | ||
static constexpr auto MSD_POS = MANT_DIG - 4; | ||
|
||
private: | ||
// |sign| bexp(7) | frac(56) | | ||
// sign: 1=negative | ||
// bexp: biased radix 16 exponent, offset 0x40, 0=zero | ||
// frac: fraction hexadecimal digits, 1/16 <= frac < 1 | ||
uint64_t _u64; | ||
}; | ||
|
||
using ibm_float32_t = __ibm_float32; | ||
using ibm_float64_t = __ibm_float64; | ||
|
||
} // namespace libasm | ||
|
||
#endif | ||
|
||
// Local Variables: | ||
// mode: c++ | ||
// c-basic-offset: 4 | ||
// tab-width: 4 | ||
// End: | ||
// vim: set ft=cpp et ts=4 sw=4: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.