@@ -631,7 +631,8 @@ PPC32Emulator::Assembler::Argument::Argument(const string& text, bool raw)
631631 } catch (const invalid_argument&) {
632632 }
633633
634- // If we really can't figure out what it is, assume it's a branch target
634+ // If we really can't figure out what it is, assume it's a branch target (in
635+ // some cases, e.g. for .float, the parsing will actually occur later)
635636 this ->label_name = text;
636637 this ->type = Type::BRANCH_TARGET;
637638}
@@ -5483,6 +5484,30 @@ uint32_t PPC32Emulator::Assembler::asm_data(const StreamItem& si) {
54835484 }
54845485}
54855486
5487+ uint32_t PPC32Emulator::Assembler::asm_float (const StreamItem& si) {
5488+ if (si.args .size () != 1 ) {
5489+ throw std::runtime_error (" incorrect argument count for .data" );
5490+ }
5491+ const auto & arg = si.args [0 ];
5492+
5493+ union {
5494+ float f;
5495+ uint32_t u;
5496+ } value;
5497+
5498+ if (arg.type == ArgType::BRANCH_TARGET) {
5499+ if (arg.label_name .empty ()) {
5500+ throw runtime_error (" incorrect argument type for .offsetof" );
5501+ }
5502+ value.f = stof (arg.label_name , nullptr );
5503+ } else {
5504+ si.check_args ({ArgType::IMMEDIATE});
5505+ value.f = arg.value ;
5506+ }
5507+
5508+ return value.u ;
5509+ }
5510+
54865511uint32_t PPC32Emulator::Assembler::asm_offsetof (const StreamItem& si) {
54875512 const auto & a = si.check_args ({ArgType::BRANCH_TARGET});
54885513 if (a[0 ].label_name .empty ()) {
@@ -6054,6 +6079,7 @@ const unordered_map<string, PPC32Emulator::Assembler::AssembleFunction>
60546079 {" mtfsf" , &PPC32Emulator::Assembler::asm_mtfsf},
60556080 {" mtfsf." , &PPC32Emulator::Assembler::asm_mtfsf},
60566081 {" .data" , &PPC32Emulator::Assembler::asm_data},
6082+ {" .float" , &PPC32Emulator::Assembler::asm_float},
60576083 {" .offsetof" , &PPC32Emulator::Assembler::asm_offsetof},
60586084 {" .deltaof" , &PPC32Emulator::Assembler::asm_deltaof},
60596085};
@@ -6405,7 +6431,7 @@ void PPC32Emulator::Assembler::assemble(const string& text, function<string(cons
64056431 const auto & arg = args.at (0 );
64066432 if (arg.type == ArgType::BRANCH_TARGET) {
64076433 if (arg.label_name .empty ()) {
6408- throw std::runtime_error (" incorrect arguemnt type for .address directive" );
6434+ throw std::runtime_error (" incorrect argument type for .address directive" );
64096435 }
64106436 si_address = this ->label_addresses .at (arg.label_name );
64116437 } else if (arg.type == ArgType::IMMEDIATE) {
0 commit comments