Add l suffix to yoink nop

main
Justine Tunney 2020-12-28 11:38:38 -08:00
parent de09bec215
commit 12065100e1
4 changed files with 26 additions and 24 deletions

View File

@ -784,7 +784,7 @@ typedef uint64_t uintmax_t;
} while (0) } while (0)
#define STATIC_YOINK(SYMBOLSTR) \ #define STATIC_YOINK(SYMBOLSTR) \
asm(".pushsection .yoink\n\tnop\t\"" SYMBOLSTR "\"\n\t.popsection") asm(".pushsection .yoink\n\tnopl\t\"" SYMBOLSTR "\"\n\t.popsection")
#if !defined(IM_FEELING_NAUGHTY) && !defined(__STRICT_ANSI__) #if !defined(IM_FEELING_NAUGHTY) && !defined(__STRICT_ANSI__)
#define STATIC_YOINK_SOURCE(PATH) STATIC_YOINK(PATH) #define STATIC_YOINK_SOURCE(PATH) STATIC_YOINK(PATH)

View File

@ -22,7 +22,9 @@
#include "libc/fmt/conv.h" #include "libc/fmt/conv.h"
#include "libc/log/check.h" #include "libc/log/check.h"
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/nexgen32e/bsr.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
#include "libc/str/str.h" #include "libc/str/str.h"
@ -133,12 +135,10 @@
#define ISRIP 0x00080000 #define ISRIP 0x00080000
#define ISREG 0x00100000 #define ISREG 0x00100000
#define APPEND(L) L.p = realloc(L.p, ++L.n * sizeof(*L.p)) #define APPEND(L) L.p = realloc(L.p, ++L.n * sizeof(*L.p))
#define IS(P, N, S) (N == sizeof(S) - 1 && !strncasecmp(P, S, sizeof(S) - 1)) #define IS(P, N, S) (N == sizeof(S) - 1 && !strncasecmp(P, S, sizeof(S) - 1))
#define BSR(I) (__builtin_clz(I) ^ 31) #define MAX(X, Y) ((Y) < (X) ? (X) : (Y))
#define ROUNDUP(X, K) (((X) + (K)-1) & -(K)) #define LOAD128BE(S) ((unsigned __int128)LOAD64BE(S) << 64 | LOAD64BE((S) + 8))
#define MAX(X, Y) ((Y) < (X) ? (X) : (Y))
#define LOAD128BE(S) ((unsigned __int128)LOAD64BE(S) << 64 | LOAD64BE((S) + 8))
#define LOAD64BE(S) \ #define LOAD64BE(S) \
((unsigned long)((unsigned char *)(S))[0] << 070 | \ ((unsigned long)((unsigned char *)(S))[0] << 070 | \
(unsigned long)((unsigned char *)(S))[1] << 060 | \ (unsigned long)((unsigned char *)(S))[1] << 060 | \
@ -148,8 +148,6 @@
(unsigned long)((unsigned char *)(S))[5] << 020 | \ (unsigned long)((unsigned char *)(S))[5] << 020 | \
(unsigned long)((unsigned char *)(S))[6] << 010 | \ (unsigned long)((unsigned char *)(S))[6] << 010 | \
(unsigned long)((unsigned char *)(S))[7] << 000) (unsigned long)((unsigned char *)(S))[7] << 000)
#define ARRAYLEN(A) \
((sizeof(A) / sizeof(*(A))) / ((unsigned)!(sizeof(A) % sizeof(*(A)))))
struct As { struct As {
int i; // things int i; // things
@ -2011,7 +2009,7 @@ static int ParseModrm(struct As *a, int *disp) {
modrm |= reg & 0xff00; // rex modrm |= reg & 0xff00; // rex
if (((reg & 070) >> 3) == 2) modrm |= HASASZ; // asz if (((reg & 070) >> 3) == 2) modrm |= HASASZ; // asz
if (!IsPunct(a, a->i, ')')) { if (!IsPunct(a, a->i, ')')) {
modrm |= (BSR(GetInt(a)) & 3) << 6; modrm |= (bsr(GetInt(a)) & 3) << 6;
} }
} else { } else {
modrm |= 4 << 3; // puttin' on the riz modrm |= 4 << 3; // puttin' on the riz
@ -2118,23 +2116,23 @@ static void OnMov(struct As *a, struct Slice s) {
switch ((reg & 070) >> 3) { switch ((reg & 070) >> 3) {
case 0: case 0:
EmitRex(a, reg); EmitRex(a, reg);
EmitByte(a, 0xb0 + (reg & 7)); EmitByte(a, 0xB0 + (reg & 7));
EmitExpr(a, imm, R_X86_64_8, EmitByte); EmitExpr(a, imm, R_X86_64_8, EmitByte);
break; break;
case 1: case 1:
EmitRex(a, reg); EmitRex(a, reg);
EmitByte(a, OSZ); EmitByte(a, OSZ);
EmitByte(a, 0xb8 + (reg & 7)); EmitByte(a, 0xB8 + (reg & 7));
EmitExpr(a, imm, R_X86_64_16, EmitWord); EmitExpr(a, imm, R_X86_64_16, EmitWord);
break; break;
case 2: case 2:
EmitRex(a, reg); EmitRex(a, reg);
EmitByte(a, 0xb8 + (reg & 7)); EmitByte(a, 0xB8 + (reg & 7));
EmitExpr(a, imm, R_X86_64_32, EmitLong); EmitExpr(a, imm, R_X86_64_32, EmitLong);
break; break;
case 3: case 3:
EmitRex(a, reg); EmitRex(a, reg);
EmitByte(a, 0xb8 + (reg & 7)); // suboptimal EmitByte(a, 0xB8 + (reg & 7)); // suboptimal
EmitExpr(a, imm, R_X86_64_64, EmitQuad); EmitExpr(a, imm, R_X86_64_64, EmitQuad);
break; break;
default: default:
@ -2145,26 +2143,26 @@ static void OnMov(struct As *a, struct Slice s) {
switch (GetOpSize(a, s, modrm, 1)) { switch (GetOpSize(a, s, modrm, 1)) {
case 0: case 0:
EmitRex(a, modrm); EmitRex(a, modrm);
EmitByte(a, 0xc6); EmitByte(a, 0xC6);
EmitModrm(a, 0, modrm, disp); EmitModrm(a, 0, modrm, disp);
EmitExpr(a, imm, R_X86_64_8, EmitByte); EmitExpr(a, imm, R_X86_64_8, EmitByte);
break; break;
case 1: case 1:
EmitByte(a, OSZ); EmitByte(a, OSZ);
EmitRex(a, modrm); EmitRex(a, modrm);
EmitByte(a, 0xc7); EmitByte(a, 0xC7);
EmitModrm(a, 0, modrm, disp); EmitModrm(a, 0, modrm, disp);
EmitExpr(a, imm, R_X86_64_16, EmitWord); EmitExpr(a, imm, R_X86_64_16, EmitWord);
break; break;
case 2: case 2:
EmitRex(a, modrm); EmitRex(a, modrm);
EmitByte(a, 0xc7); EmitByte(a, 0xC7);
EmitModrm(a, 0, modrm, disp); EmitModrm(a, 0, modrm, disp);
EmitExpr(a, imm, R_X86_64_32, EmitLong); EmitExpr(a, imm, R_X86_64_32, EmitLong);
break; break;
case 3: case 3:
EmitRex(a, modrm | REXW << 8); EmitRex(a, modrm | REXW << 8);
EmitByte(a, 0xc7); // suboptimal EmitByte(a, 0xC7); // suboptimal
EmitModrm(a, 0, modrm, disp); EmitModrm(a, 0, modrm, disp);
EmitExpr(a, imm, R_X86_64_32, EmitLong); EmitExpr(a, imm, R_X86_64_32, EmitLong);
break; break;

View File

@ -3,7 +3,7 @@
float g40 = 1.5; float g40 = 1.5;
double g41 = 0.0 ? 55 : (0, 1 + 1 * 5.0 / 2 * (double)2 * (int)2.0); double g41 = 0.0 ? 55 : (0, 1 + 1 * 5.0 / 2 * (double)2 * (int)2.0);
int main() { int main(int argc, char *argv[]) {
ASSERT(10, ({ ASSERT(10, ({
enum { ten = 1 + 2 + 3 + 4 }; enum { ten = 1 + 2 + 3 + 4 };
ten; ten;
@ -129,15 +129,15 @@ int main() {
sizeof(x); sizeof(x);
})); }));
ASSERT(8, ({ ASSERT(8, ({
char x[(int*)0 + 2]; char x[(int *)0 + 2];
sizeof(x); sizeof(x);
})); }));
ASSERT(12, ({ ASSERT(12, ({
char x[(int*)16 - 1]; char x[(int *)16 - 1];
sizeof(x); sizeof(x);
})); }));
ASSERT(3, ({ ASSERT(3, ({
char x[(int*)16 - (int*)4]; char x[(int *)16 - (int *)4];
sizeof(x); sizeof(x);
})); }));

View File

@ -242,10 +242,14 @@ void add_type(Node *node) {
node->ty = node->lhs->ty; node->ty = node->lhs->ty;
} else { } else {
#endif #endif
if (!node->lhs->ty->base) if (!node->lhs->ty->base) {
error_tok(node->tok, "invalid pointer dereference"); error_tok(node->tok, "invalid pointer dereference");
if (node->lhs->ty->base->kind == TY_VOID) }
if (node->lhs->ty->base->kind == TY_VOID) {
/* TODO(jart): Does standard permit this? */
/* https://lkml.org/lkml/2018/3/20/845 */
error_tok(node->tok, "dereferencing a void pointer"); error_tok(node->tok, "dereferencing a void pointer");
}
node->ty = node->lhs->ty->base; node->ty = node->lhs->ty->base;
#if 0 #if 0
} }