From 37c859058d678dc30d4bc2dee985d7a5e2d07db0 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Thu, 1 Aug 2019 14:50:19 -0700 Subject: table-based register conversion Requires a change to the C++ translator: support string literals in all segments, not just the code segment. (The self-hosted translator already had this.) --- 038---literal_strings.cc | 62 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 20 deletions(-) (limited to '038---literal_strings.cc') diff --git a/038---literal_strings.cc b/038---literal_strings.cc index 547747a6..48d46108 100644 --- a/038---literal_strings.cc +++ b/038---literal_strings.cc @@ -12,7 +12,7 @@ void test_transform_literal_string() { CHECK_TRACE_CONTENTS( "transform: -- move literal strings to data segment\n" "transform: adding global variable '__subx_global_1' containing \"test\"\n" - "transform: instruction after transform: 'b8 __subx_global_1'\n" + "transform: line after transform: 'b8 __subx_global_1'\n" ); } @@ -32,33 +32,40 @@ Next_auto_global = 1; void transform_literal_strings(program& p) { trace(3, "transform") << "-- move literal strings to data segment" << end(); if (p.segments.empty()) return; - segment& code = *find(p, "code"); - segment& data = *find(p, "data"); - for (int i = 0; i < SIZE(code.lines); ++i) { - line& inst = code.lines.at(i); - for (int j = 0; j < SIZE(inst.words); ++j) { - word& curr = inst.words.at(j); - if (curr.data.at(0) != '"') continue; - ostringstream global_name; - global_name << "__subx_global_" << Next_auto_global; - ++Next_auto_global; - add_global_to_data_segment(global_name.str(), curr, data); - curr.data = global_name.str(); + vector new_lines; + for (int s = 0; s < SIZE(p.segments); ++s) { + segment& seg = p.segments.at(s); + trace(99, "transform") << "segment '" << seg.name << "'" << end(); + for (int i = 0; i < SIZE(seg.lines); ++i) { +//? cerr << seg.name << '/' << i << '\n'; + line& line = seg.lines.at(i); + for (int j = 0; j < SIZE(line.words); ++j) { + word& curr = line.words.at(j); + if (curr.data.at(0) != '"') continue; + ostringstream global_name; + global_name << "__subx_global_" << Next_auto_global; + ++Next_auto_global; + add_global_to_data_segment(global_name.str(), curr, new_lines); + curr.data = global_name.str(); + } + trace(99, "transform") << "line after transform: '" << data_to_string(line) << "'" << end(); } - trace(99, "transform") << "instruction after transform: '" << data_to_string(inst) << "'" << end(); } + segment* data = find(p, "data"); + if (data) + data->lines.insert(data->lines.end(), new_lines.begin(), new_lines.end()); } -void add_global_to_data_segment(const string& name, const word& value, segment& data) { +void add_global_to_data_segment(const string& name, const word& value, vector& out) { trace(99, "transform") << "adding global variable '" << name << "' containing " << value.data << end(); // emit label - data.lines.push_back(label(name)); + out.push_back(label(name)); // emit size for size-prefixed array - data.lines.push_back(line()); - emit_hex_bytes(data.lines.back(), SIZE(value.data)-/*skip quotes*/2, 4/*bytes*/); + out.push_back(line()); + emit_hex_bytes(out.back(), SIZE(value.data)-/*skip quotes*/2, 4/*bytes*/); // emit data byte by byte - data.lines.push_back(line()); - line& curr = data.lines.back(); + out.push_back(line()); + line& curr = out.back(); for (int i = /*skip start quote*/1; i < SIZE(value.data)-/*skip end quote*/1; ++i) { char c = value.data.at(i); curr.words.push_back(word()); @@ -83,6 +90,21 @@ void test_instruction_with_string_literal() { CHECK_TRACE_COUNT("parse2", 3); } +void test_string_literal_in_data_segment() { + run( + "== code 0x1\n" + "b8/copy X/imm32\n" + "== data 0x2000\n" + "X:\n" + "\"test\"/imm32\n" + ); + CHECK_TRACE_CONTENTS( + "transform: -- move literal strings to data segment\n" + "transform: adding global variable '__subx_global_1' containing \"test\"\n" + "transform: line after transform: '__subx_global_1'\n" + ); +} + :(before "End Line Parsing Special-cases(line_data -> l)") if (line_data.find('"') != string::npos) { // can cause false-positives, but we can handle them parse_instruction_character_by_character(line_data, l); -- cgit 1.4.1-2-gfad0