Skip to content

Instantly share code, notes, and snippets.

View rui314's full-sized avatar

Rui Ueyama rui314

  • Blue Whale Systems
  • Tokyo
View GitHub Profile
@rui314
rui314 / gist:2014832
Created March 11, 2012 03:16
N queen
int print_board(int *board) {
for (int i = 0; i < 8; i = i + 1) {
for (int j = 0; j < 8; j =j +1) {
int *v = board + i * 8 + j;
if (*v) {
printf("Q ");
} else {
printf(". ");
}
}
@rui314
rui314 / gist:2018964
Created March 12, 2012 00:51
N queen
int print_board(int board[][8]) {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (board[i][j])
printf("Q ");
else
printf(". ");
}
printf("\n");
}
@rui314
rui314 / gist:6959261
Created October 13, 2013 07:42
A nqueen solver that works on my lisp implemenation (https://github.com/rui314/minilisp)
(defun list (expr . rest)
(cons expr rest))
(defun zero? (expr)
(= expr 0))
(defun nil? (expr)
(eq expr ()))
(defmacro let1 (var val . body)
diff --git a/src/util.cc b/src/util.cc
index 746d7ed..3a3c7df 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -190,6 +190,9 @@ bool CanonicalizePath(char* path, size_t* len, unsigned int* slash_bits,
bits_offset--;
bits = ShiftOverBit(bits_offset, bits);
#endif
+ } else if (*start == '/') {
+ src += 3;
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index b885601..1a6fbc1 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -1385,18 +1385,22 @@ StringTableSection<ELFT>::StringTableSection(StringRef Name, bool Dynamic)
// we obtained in the former function can be written in the latter.
// This design eliminated that need.
template <class ELFT> void StringTableSection<ELFT>::reserve(StringRef S) {
- Reserved += S.size() + 1; // +1 for NUL
+ if (Seen.insert(S).second)
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index c941993..cefdb46 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -844,8 +844,8 @@ static bool compCtors(const InputSection<ELFT> *A,
assert(Y.startswith(".ctors") || Y.startswith(".dtors"));
X = X.substr(6);
Y = Y.substr(6);
- if (X.empty() || Y.empty())
- return X.empty();
Before
415.548666 task-clock (msec) # 1.000 CPUs utilized ( +- 0.42% )
25 context-switches # 0.061 K/sec ( +- 4.42% )
1 cpu-migrations # 0.002 K/sec ( +- 28.86% )
60,001 page-faults # 0.144 M/sec
1,159,320,437 cycles # 2.790 GHz ( +- 0.42% )
713,987,937 stalled-cycles-frontend # 61.59% frontend cycles idle ( +- 0.68% )
<not supported> stalled-cycles-backend
1,151,611,502 instructions # 0.99 insns per cycle
# 0.62 stalled cycles per insn ( +- 0.02% )

A C compiler for Brainfuck

I want to share my friend's crazy project because it demonstrates how a simple Turing-machine-like programming language is actually equivalent to usual real-world computers.

I think we all know the theory that all Turing complete programming languages are equivalent in terms of their powers. If languages A and B are Turing complete, A can emulate B and vice versa. But that's not obvious at all. How can a simple programming model like Turing Machine can run "real" programs such as ones that run on a general-purpose PC? If it is possible in theory, it can be demonstrated.

#include <stdio.h>
#include <stdlib.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define _GNU_SOURCE
#include <fcntl.h>

MIPSのABIは変だという話をこないだのシステムプログラミング会でしたら、ややザワッとしたので、なにがおかしいのかというのをちょっとまとめてみました。まとめてみて思いましたが、やっぱりMIPSのELFファイルはちょっと変です。

謎のmixed endianフィールド

これが僕は一番ひどいと思ったものです。

ファイルにマルチバイトの数値を保存するときはエンディアンというものが問題になります。たとえば0xBEEFという2バイトの数を保存するときは、1バイト目にBE、2バイト目にEFを書くか、逆順で書くかは、ただの決まり事でどっちでもいいわけですが、書く側と読む側で認識があっていないと困ります。世の中的にはリトルエンディアン(下位バイトから書く)のが主流ですがビッグエンディアンなシステムもあります。

それがですね、MIPSのELFヘッダのr_infoという64ビットのフィールドはリトルエンディアンでもビッグエンディアンでもない謎なエンコーディングになっています。具体的には下位32ビットが最初にリトルエンディアンで書かれていて、ビッグエンディアンでエンコードされた上位32ビットがそれに続くという構成になっています。つまりリトルエンディアンだとABCD EFGH、ビッグエンディアンだとHGFE DCBAとなるところが、MIPSのmixed endianだとEFGH DCBAというふうにファイルに書かれていることになります。