[前][次][番号順一覧][スレッド一覧]

ruby-changes:68566

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:08:41 +0900 (JST)
Subject: [ruby-changes:68566] 6a12fb2067 (master): Ported label linking and conditional jumps

https://git.ruby-lang.org/ruby.git/commit/?id=6a12fb2067

From 6a12fb2067e1d0a9ce610b0affd6a3113d13ff1c Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Fri, 11 Sep 2020 15:10:16 -0400
Subject: Ported label linking and conditional jumps

---
 ujit_asm.c       | 175 ++++++++++++++++++++++++++++++++++++++-----------------
 ujit_asm.h       |  41 ++++++++++++-
 ujit_asm_tests.c |  28 +++++----
 3 files changed, 179 insertions(+), 65 deletions(-)

diff --git a/ujit_asm.c b/ujit_asm.c
index a7c673ef92..edc0672300 100644
--- a/ujit_asm.c
+++ b/ujit_asm.c
@@ -226,6 +226,72 @@ void cb_write_epilogue(codeblock_t* cb) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L226
         cb_write_byte(cb, ujit_post_call_bytes[i]);
 }
 
+// Allocate a new label with a given name
+size_t cb_new_label(codeblock_t* cb, const char* name)
+{
+    //if (hasASM)
+    //    writeString(to!string(label) ~ ":");
+
+    assert (cb->num_labels < MAX_LABELS);
+
+    // Allocate the new label
+    size_t label_idx = cb->num_labels++;
+
+    // This label doesn't have an address yet
+    cb->label_addrs[label_idx] = 0;
+    cb->label_names[label_idx] = name;
+
+    return label_idx;
+}
+
+// Write a label at the current address
+void cb_write_label(codeblock_t* cb, size_t label_idx)
+{
+    assert (label_idx < MAX_LABELS);
+    cb->label_addrs[label_idx] = cb->write_pos;
+}
+
+// Add a label reference at the current write position
+void cb_label_ref(codeblock_t* cb, size_t label_idx)
+{
+    assert (label_idx < MAX_LABELS);
+    assert (cb->num_refs < MAX_LABEL_REFS);
+
+    // Keep track of the reference
+    cb->label_refs[cb->num_refs] = (labelref_t){ cb->write_pos, label_idx };
+    cb->num_refs++;
+}
+
+// Link internal label references
+void cb_link_labels(codeblock_t* cb)
+{
+    size_t orig_pos = cb->write_pos;
+
+    // For each label reference
+    for (size_t i = 0; i < cb->num_refs; ++i)
+    {
+        size_t ref_pos = cb->label_refs[i].pos;
+        size_t label_idx = cb->label_refs[i].label_idx;
+        assert (ref_pos < cb->mem_size);
+        assert (label_idx < MAX_LABELS);
+
+        size_t label_addr = cb->label_addrs[label_idx];
+        assert (label_addr < cb->mem_size);
+
+        // Compute the offset from the reference's end to the label
+        int64_t offset = (int64_t)label_addr - (int64_t)(ref_pos + 4);
+
+        cb_set_pos(cb, ref_pos);
+        cb_write_int(cb, offset, 32);
+    }
+
+    cb->write_pos = orig_pos;
+
+    // Clear the label positions and references
+    cb->num_labels = 0;
+    cb->num_refs = 0;
+}
+
 // Check if an operand needs a REX byte to be encoded
 bool rex_needed(x86opnd_t opnd)
 {
@@ -681,79 +747,82 @@ void call(codeblock_t* cb, x86opnd_t opnd) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L747
     cb_write_rm(cb, false, false, NO_OPND, opnd, 2, 1, 0xFF);
 }
 
-/**
-Encode a relative jump to a label (direct or conditional)
-Note: this always encodes a 32-bit offset
-*/
-/*
-void writeJcc(string mnem, opcode...)(CodeBlock cb, Label label)
+// Encode a relative jump to a label (direct or conditional)
+// Note: this always encodes a 32-bit offset
+void cb_write_jcc(codeblock_t* cb, const char* mnem, uint8_t op0, uint8_t op1, size_t label_idx)
 {
-    cb.writeASM(mnem, label);
+    //cb.writeASM(mnem, label);
 
     // Write the opcode
-    cb.writeBytes(opcode);
+    cb_write_byte(cb, op0);
+    cb_write_byte(cb, op1);
 
     // Add a reference to the label
-    cb.addLabelRef(label);
+    cb_label_ref(cb, label_idx);
 
     // Relative 32-bit offset to be patched
-    cb.writeInt(0, 32);
+    cb_write_int(cb, 0, 32);
 }
-*/
 
-/*
 /// jcc - Conditional relative jump to a label
-alias ja = writeJcc!("ja", 0x0F, 0x87);
-alias jae = writeJcc!("jae", 0x0F, 0x83);
-alias jb = writeJcc!("jb", 0x0F, 0x82);
-alias jbe = writeJcc!("jbe", 0x0F, 0x86);
-alias jc = writeJcc!("jc", 0x0F, 0x82);
-alias je = writeJcc!("je", 0x0F, 0x84);
-alias jg = writeJcc!("jg", 0x0F, 0x8F);
-alias jge = writeJcc!("jge", 0x0F, 0x8D);
-alias jl = writeJcc!("jl", 0x0F, 0x8C);
-alias jle = writeJcc!("jle", 0x0F, 0x8E);
-alias jna = writeJcc!("jna", 0x0F, 0x86);
-alias jnae = writeJcc!("jnae", 0x0F, 0x82);
-alias jnb = writeJcc!("jnb", 0x0F, 0x83);
-alias jnbe = writeJcc!("jnbe", 0x0F, 0x87);
-alias jnc = writeJcc!("jnc", 0x0F, 0x83);
-alias jne = writeJcc!("jne", 0x0F, 0x85);
-alias jng = writeJcc!("jng", 0x0F, 0x8E);
-alias jnge = writeJcc!("jnge", 0x0F, 0x8C);
-alias jnl = writeJcc!("jnl", 0x0F, 0x8D);
-alias jnle = writeJcc!("jnle", 0x0F, 0x8F);
-alias jno = writeJcc!("jno", 0x0F, 0x81);
-alias jnp = writeJcc!("jnp", 0x0F, 0x8b);
-alias jns = writeJcc!("jns", 0x0F, 0x89);
-alias jnz = writeJcc!("jnz", 0x0F, 0x85);
-alias jo = writeJcc!("jo", 0x0F, 0x80);
-alias jp = writeJcc!("jp", 0x0F, 0x8A);
-alias jpe = writeJcc!("jpe", 0x0F, 0x8A);
-alias jpo = writeJcc!("jpo", 0x0F, 0x8B);
-alias js = writeJcc!("js", 0x0F, 0x88);
-alias jz = writeJcc!("jz", 0x0F, 0x84);
+void ja  (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "ja"  , 0x0F, 0x87, label_idx); }
+void jae (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jae" , 0x0F, 0x83, label_idx); }
+void jb  (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jb"  , 0x0F, 0x82, label_idx); }
+void jbe (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jbe" , 0x0F, 0x86, label_idx); }
+void jc  (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jc"  , 0x0F, 0x82, label_idx); }
+void je  (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "je"  , 0x0F, 0x84, label_idx); }
+void jg  (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jg"  , 0x0F, 0x8F, label_idx); }
+void jge (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jge" , 0x0F, 0x8D, label_idx); }
+void jl  (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jl"  , 0x0F, 0x8C, label_idx); }
+void jle (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jle" , 0x0F, 0x8E, label_idx); }
+void jna (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jna" , 0x0F, 0x86, label_idx); }
+void jnae(codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnae", 0x0F, 0x82, label_idx); }
+void jnb (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnb" , 0x0F, 0x83, label_idx); }
+void jnbe(codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnbe", 0x0F, 0x87, label_idx); }
+void jnc (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnc" , 0x0F, 0x83, label_idx); }
+void jne (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jne" , 0x0F, 0x85, label_idx); }
+void jng (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jng" , 0x0F, 0x8E, label_idx); }
+void jnge(codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnge", 0x0F, 0x8C, label_idx); }
+void jnl (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnl" , 0x0F, 0x8D, label_idx); }
+void jnle(codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnle", 0x0F, 0x8F, label_idx); }
+void jno (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jno" , 0x0F, 0x81, label_idx); }
+void jnp (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnp" , 0x0F, 0x8b, label_idx); }
+void jns (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jns" , 0x0F, 0x89, label_idx); }
+void jnz (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jnz" , 0x0F, 0x85, label_idx); }
+void jo  (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jo"  , 0x0F, 0x80, label_idx); }
+void jp  (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jp"  , 0x0F, 0x8A, label_idx); }
+void jpe (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jpe" , 0x0F, 0x8A, label_idx); }
+void jpo (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jpo" , 0x0F, 0x8B, label_idx); }
+void js  (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "js"  , 0x0F, 0x88, label_idx); }
+void jz  (codeblock_t* cb, size_t label_idx) { cb_write_jcc(cb, "jz"  , 0x0F, 0x84, label_idx); }
 
-/// Opcode for direct jump with relative 8-bit offset
-const ubyte JMP_REL8_OPCODE = 0xEB;
+/// jmp - Direct relative jump to label
+void jmp(codeblock_t* cb, size_t label_idx)
+{
+    //cb.writeASM(mnem, label);
 
-/// Opcode for direct jump with relative 32-bit offset
-const ubyte JMP_REL32_OPCODE = 0xE9;
+    /// Opcode for direct jump with relative 32-bit offset
+    cb_write_byte(cb, 0xE9);
 
-/// Opcode for jump on equal with relative 32-bit offset
-const ubyte[] JE_REL32_OPCODE = [0x0F, 0x84];
+    // Add a reference to the label
+    cb_label_ref(cb, label_idx);
 
-/// jmp - Direct relative jump to label
-alias jmp = writeJcc!("jmp", JMP_REL32_OPCODE);
-*/
+    // Relative 32-bit offset to be patched
+    cb_write_int(cb, 0, 32);
+}
 
 /// jmp - Indirect jump near to an R/M operand
-void jmp(codeblock_t* cb, x86opnd_t opnd)
+void jmp_rm(codeblock_t* cb, x86opnd_t opnd)
 {
     //cb.writeASM("jmp", opnd);
     cb_write_rm(cb, false, false, NO_OPND, opnd, 4, 1, 0xFF);
 }
 
+/*
+/// Opcode for direct jump with relative 8-bit offset
+const ubyte JMP_REL8_OPCODE = 0xEB;
+*/
+
 /*
 /// jmp - Jump with relative 8-bit offset
 void jmp8(CodeBlock cb, int8_t offset)
@@ -762,7 +831,9 @@ void jmp8(CodeBlock cb, int8_t offset) https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L831
     cb.writeByte(JMP_REL8_OPCODE);
     cb.writeByte(offset);
 }
+*/
 
+/*
 /// jmp - Jump with relative 32-bit offset
 void jmp32(CodeBlock cb, int32_t offset)
 {
diff --git a/ujit_asm.h b/ujit_asm.h
index 714bfa2f31..31d8ea44d3 100644
--- a/ujit_asm.h
+++ b/ujit_asm.h
@@ -37,6 +37,10 @@ typedef struct CodeBlock https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L37
     // Table of registered label addresses
     size_t label_addrs[MAX_LABELS];
 
+    // Table of registered label names
+    // Note that these should be constant strings only
+    const char* label_names[MAX_LABELS];
+
     // References to labels
     labelref_t label_refs[MAX_LABEL_REFS];
 
@@ -179,6 +183,10 @@ uint8_t* cb_get_ptr(codeblock_t* cb, size_t index); https://github.com/ruby/ruby/blob/trunk (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]