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

ruby-changes:68555

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:08:14 +0900 (JST)
Subject: [ruby-changes:68555] 0a5dcc056e (master): Progress on porting x86 assembler for MicroJIT

https://git.ruby-lang.org/ruby.git/commit/?id=0a5dcc056e

From 0a5dcc056e22bab849d8d7877928d300201af823 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Fri, 4 Sep 2020 15:56:00 -0400
Subject: Progress on porting x86 assembler for MicroJIT

---
 common.mk        |   2 +
 test_asm.sh      |   6 ++
 ujit_asm.c       | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ujit_asm.h       |  72 ++++++++++++++++++++++
 ujit_asm_tests.c |  31 ++++++++++
 5 files changed, 294 insertions(+)
 create mode 100755 test_asm.sh
 create mode 100644 ujit_asm.c
 create mode 100644 ujit_asm.h
 create mode 100644 ujit_asm_tests.c

diff --git a/common.mk b/common.mk
index 45ebaab86a..59d5dcea5d 100644
--- a/common.mk
+++ b/common.mk
@@ -150,6 +150,8 @@ COMMONOBJS    = array.$(OBJEXT) \ https://github.com/ruby/ruby/blob/trunk/common.mk#L150
 		vm_dump.$(OBJEXT) \
 		vm_sync.$(OBJEXT) \
 		vm_trace.$(OBJEXT) \
+		ujit_asm.$(OBJEXT) \
+		ujit_asm_tests.$(OBJEXT) \
 		$(COROUTINE_OBJ) \
 		$(DTRACE_OBJ) \
 		$(BUILTIN_ENCOBJS) \
diff --git a/test_asm.sh b/test_asm.sh
new file mode 100755
index 0000000000..446dd36d65
--- /dev/null
+++ b/test_asm.sh
@@ -0,0 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/test_asm.sh#L1
+# NOTE: I did not know what would be the sensible way to compile
+# and run these tests from the Ruby makefile
+
+clang -std=c99 -Wall ujit_asm.c ujit_asm_tests.c -o asm_test
+
+./asm_test
diff --git a/ujit_asm.c b/ujit_asm.c
new file mode 100644
index 0000000000..7ff8792059
--- /dev/null
+++ b/ujit_asm.c
@@ -0,0 +1,183 @@ https://github.com/ruby/ruby/blob/trunk/ujit_asm.c#L1
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <assert.h>
+
+// For mmapp()
+#include <sys/mman.h>
+
+#include "ujit_asm.h"
+
+// TODO: give ujit_examples.h some more meaningful file name
+#include "ujit_examples.h"
+
+void cb_init(codeblock_t* cb, size_t mem_size)
+{
+    // Map the memory as executable
+    cb->mem_block = (uint8_t*)mmap(
+        NULL,
+        mem_size,
+        PROT_READ | PROT_WRITE | PROT_EXEC,
+        MAP_PRIVATE | MAP_ANON,
+        -1,
+        0
+    );
+
+    // Check that the memory mapping was successful
+    if (cb->mem_block == MAP_FAILED)
+    {
+        fprintf(stderr, "mmap call failed\n");
+        exit(-1);
+    }
+
+    cb->mem_size = mem_size;
+    cb->write_pos = 0;
+    cb->num_labels = 0;
+    cb->num_refs = 0;
+}
+
+// Get a direct pointer into the executable memory block
+uint8_t* cb_get_ptr(codeblock_t* cb, size_t index)
+{
+    assert (index < cb->mem_size);
+    return &cb->mem_block[index];
+}
+
+// Write a byte at the current position
+void cb_write_byte(codeblock_t* cb, uint8_t byte)
+{
+    assert (cb->mem_block);
+    assert (cb->write_pos + 1 <= cb->mem_size);
+    cb->mem_block[cb->write_pos++] = byte;
+}
+
+// Write multiple bytes starting from the current position
+void cb_write_bytes(codeblock_t* cb, size_t num_bytes, ...)
+{
+    va_list va;
+    va_start(va, num_bytes);
+
+    for (size_t i = 0; i < num_bytes; ++i)
+    {
+        uint8_t byte = va_arg(va, int);
+        cb_write_byte(cb, byte);
+    }
+
+    va_end(va);
+}
+
+// Write a signed integer over a given number of bits at the current position
+void cb_write_int(codeblock_t* cb, uint64_t val, size_t num_bits)
+{
+    assert (num_bits > 0);
+    assert (num_bits % 8 == 0);
+
+    // Switch on the number of bits
+    switch (num_bits)
+    {
+        case 8:
+        cb_write_byte(cb, (uint8_t)val);
+        break;
+
+        case 16:
+        cb_write_bytes(
+            cb,
+            2,
+            (uint8_t)((val >> 0) & 0xFF),
+            (uint8_t)((val >> 8) & 0xFF)
+        );
+        break;
+
+        case 32:
+        cb_write_bytes(
+            cb,
+            4,
+            (uint8_t)((val >>  0) & 0xFF),
+            (uint8_t)((val >>  8) & 0xFF),
+            (uint8_t)((val >> 16) & 0xFF),
+            (uint8_t)((val >> 24) & 0xFF)
+        );
+        break;
+
+        default:
+        {
+            // Compute the size in bytes
+            size_t num_bytes = num_bits / 8;
+
+            // Write out the bytes
+            for (size_t i = 0; i < num_bytes; ++i)
+            {
+                uint8_t byte_val = (uint8_t)(val & 0xFF);
+                cb_write_byte(cb, byte_val);
+                val >>= 8;
+            }
+        }
+    }
+}
+
+// nop - Noop, one or multiple bytes long
+void nop(codeblock_t* cb, size_t length)
+{
+    switch (length)
+    {
+        case 0:
+        break;
+
+        case 1:
+        //cb.writeASM("nop1");
+        cb_write_byte(cb, 0x90);
+        break;
+
+        case 2:
+        //cb.writeASM("nop2");
+        cb_write_bytes(cb, 2, 0x66,0x90);
+        break;
+
+        case 3:
+        //cb.writeASM("nop3");
+        cb_write_bytes(cb, 3, 0x0F,0x1F,0x00);
+        break;
+
+        case 4:
+        //cb.writeASM("nop4");
+        cb_write_bytes(cb, 4, 0x0F,0x1F,0x40,0x00);
+        break;
+
+        case 5:
+        //cb.writeASM("nop5");
+        cb_write_bytes(cb, 5, 0x0F,0x1F,0x44,0x00,0x00);
+        break;
+
+        case 6:
+        //cb.writeASM("nop6");
+        cb_write_bytes(cb, 6, 0x66,0x0F,0x1F,0x44,0x00,0x00);
+        break;
+
+        case 7:
+        //cb.writeASM("nop7");
+        cb_write_bytes(cb, 7, 0x0F,0x1F,0x80,0x00,0x00,0x00,0x00);
+        break;
+
+        case 8:
+        //cb.writeASM("nop8");
+        cb_write_bytes(cb, 8, 0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00);
+        break;
+
+        case 9:
+        //cb.writeASM("nop9");
+        cb_write_bytes(cb, 9, 0x66,0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00);
+        break;
+
+        default:
+        {
+            size_t written = 0;
+            while (written + 9 <= length)
+            {
+                nop(cb, 9);
+                written += 9;
+            }
+            nop(cb, length - written);
+        }
+        break;
+    }
+}
diff --git a/ujit_asm.h b/ujit_asm.h
new file mode 100644
index 0000000000..998c171d5d
--- /dev/null
+++ b/ujit_asm.h
@@ -0,0 +1,72 @@ https://github.com/ruby/ruby/blob/trunk/ujit_asm.h#L1
+#ifndef UJIT_ASM_H
+#define UJIT_ASM_H 1
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+// Maximum number of labels to link
+#define MAX_LABELS 32
+
+// Maximum number of label references
+#define MAX_LABEL_REFS 32
+
+typedef struct LabelRef
+{
+    // Position where the label reference is in the code block
+    size_t pos;
+
+    // Label which this refers to
+    size_t label_idx;
+
+} labelref_t;
+
+typedef struct CodeBlock
+{
+    // Memory block
+    uint8_t* mem_block;
+
+    // Memory block size
+    size_t mem_size;
+
+    /// Current writing position
+    size_t write_pos;
+
+    // Table of registered label addresses
+    size_t label_addrs[MAX_LABELS];
+
+    // References to labels
+    labelref_t label_refs[MAX_LABEL_REFS];
+
+    // Number of labels registeered
+    size_t num_labels;
+
+    // Number of references to labels
+    size_t num_refs;
+
+    // TODO: system for disassembly/comment strings, indexed by position
+
+    // Flag to enable or disable comments
+    bool has_asm;
+
+} codeblock_t;
+
+void cb_init(codeblock_t* cb, size_t mem_size);
+uint8_t* cb_get_ptr(codeblock_t* cb, size_t index);
+void cb_write_byte(codeblock_t* cb, uint8_t byte);
+void cb_write_bytes(codeblock_t* cb, size_t num_bytes, ...);
+void cb_write_int(codeblock_t* cb, uint64_t val, size_t num_bits);
+
+// TODO:
+// prologue and epilogue functions
+// cb_write_prologue()
+// cb_write_epilogue
+// Test those out
+
+void nop(codeblock_t* cb, size_t length);
+
+
+
+
+
+#endif
diff --git a/ujit_asm_tests.c b/ujit_asm_tests.c
new file mode 100644
index 0000000000..0c94fb8b04
--- /dev/null
+++ b/ujit_asm_tests.c
@@ -0,0 +1,31 @@ https://github.com/ruby/ruby/blob/trunk/ujit_asm_tests.c#L1
+#include <stdio.h>
+#include <stdlib.h>
+#include "ujit_asm.h"
+
+//fprintf(stderr, format);
+//exit(-1)
+
+void run_tests()
+{
+    printf("Running assembler tests\n");
+
+    codeblock_t cb;
+    cb_init(&cb, 4096);
+
+
+
+
+
+
+
+
+
+    printf("Assembler tests done\n");
+}
+
+int main(int argc, char** argv)
+{
+    run_tests();
+
+    return 0;
+}
-- 
cgit v1.2.1


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

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