| author | |
| committer | |
| log | 9cdb5dec7aed4a1f692f4ddac034d1f944c0a837 |
| tree | 51e4087be00b41366230a43f1a65602d4e01b4da |
| parent | a5e4e205c8a9f2706300a4dc7ebe7cf3bfe093cd |
4 files changed, 76 insertions(+), 6 deletions(-)
src/analyze.cpp-4| ... | @@ -163,10 +163,6 @@ static TypeTableEntry *new_container_type_entry(TypeTableEntryId id, AstNode *so | ... | @@ -163,10 +163,6 @@ static TypeTableEntry *new_container_type_entry(TypeTableEntryId id, AstNode *so |
| 163 | return entry; | 163 | return entry; |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | static uint8_t log2_u64(uint64_t x) { | ||
| 167 | return (63 - clzll(x)); | ||
| 168 | } | ||
| 169 | |||
| 170 | static uint8_t bits_needed_for_unsigned(uint64_t x) { | 166 | static uint8_t bits_needed_for_unsigned(uint64_t x) { |
| 171 | if (x == 0) { | 167 | if (x == 0) { |
| 172 | return 0; | 168 | return 0; |
src/parsec.cpp+51| ... | @@ -347,9 +347,60 @@ static AstNode* trans_c_cast(Context *c, const SourceLocation &source_location, | ... | @@ -347,9 +347,60 @@ static AstNode* trans_c_cast(Context *c, const SourceLocation &source_location, |
| 347 | return trans_create_node_fn_call_1(c, trans_qual_type(c, qt, source_location), expr); | 347 | return trans_create_node_fn_call_1(c, trans_qual_type(c, qt, source_location), expr); |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) { | ||
| 351 | const Type *ty = qt.getTypePtr(); | ||
| 352 | switch (ty->getTypeClass()) { | ||
| 353 | case Type::Builtin: | ||
| 354 | { | ||
| 355 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty); | ||
| 356 | switch (builtin_ty->getKind()) { | ||
| 357 | case BuiltinType::Char_U: | ||
| 358 | case BuiltinType::UChar: | ||
| 359 | case BuiltinType::Char_S: | ||
| 360 | case BuiltinType::SChar: | ||
| 361 | return 8; | ||
| 362 | case BuiltinType::UInt128: | ||
| 363 | case BuiltinType::Int128: | ||
| 364 | return 128; | ||
| 365 | default: | ||
| 366 | return 0; | ||
| 367 | } | ||
| 368 | zig_unreachable(); | ||
| 369 | } | ||
| 370 | case Type::Typedef: | ||
| 371 | { | ||
| 372 | const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty); | ||
| 373 | const TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); | ||
| 374 | const char *type_name = decl_name(typedef_decl); | ||
| 375 | if (strcmp(type_name, "uint8_t") == 0 || strcmp(type_name, "int8_t") == 0) { | ||
| 376 | return 8; | ||
| 377 | } else if (strcmp(type_name, "uint16_t") == 0 || strcmp(type_name, "int16_t") == 0) { | ||
| 378 | return 16; | ||
| 379 | } else if (strcmp(type_name, "uint32_t") == 0 || strcmp(type_name, "int32_t") == 0) { | ||
| 380 | return 32; | ||
| 381 | } else if (strcmp(type_name, "uint64_t") == 0 || strcmp(type_name, "int64_t") == 0) { | ||
| 382 | return 64; | ||
| 383 | } else { | ||
| 384 | return 0; | ||
| 385 | } | ||
| 386 | } | ||
| 387 | default: | ||
| 388 | return 0; | ||
| 389 | } | ||
| 390 | zig_unreachable(); | ||
| 391 | } | ||
| 392 | |||
| 393 | |||
| 350 | static AstNode *qual_type_to_log2_int_ref(Context *c, const QualType &qt, | 394 | static AstNode *qual_type_to_log2_int_ref(Context *c, const QualType &qt, |
| 351 | const SourceLocation &source_loc) | 395 | const SourceLocation &source_loc) |
| 352 | { | 396 | { |
| 397 | uint32_t int_bit_width = qual_type_int_bit_width(c, qt, source_loc); | ||
| 398 | if (int_bit_width != 0) { | ||
| 399 | // we can perform the log2 now. | ||
| 400 | uint64_t cast_bit_width = log2_u64(int_bit_width); | ||
| 401 | return trans_create_node_symbol(c, buf_sprintf("u%" ZIG_PRI_u64, cast_bit_width)); | ||
| 402 | } | ||
| 403 | |||
| 353 | AstNode *zig_type_node = trans_qual_type(c, qt, source_loc); | 404 | AstNode *zig_type_node = trans_qual_type(c, qt, source_loc); |
| 354 | 405 | ||
| 355 | // @import("std").math.Log2Int(c_long); | 406 | // @import("std").math.Log2Int(c_long); |
src/util.hpp+4| ... | @@ -147,4 +147,8 @@ bool uint64_eq(uint64_t a, uint64_t b); | ... | @@ -147,4 +147,8 @@ bool uint64_eq(uint64_t a, uint64_t b); |
| 147 | uint32_t ptr_hash(const void *ptr); | 147 | uint32_t ptr_hash(const void *ptr); |
| 148 | bool ptr_eq(const void *a, const void *b); | 148 | bool ptr_eq(const void *a, const void *b); |
| 149 | 149 | ||
| 150 | static inline uint8_t log2_u64(uint64_t x) { | ||
| 151 | return (63 - clzll(x)); | ||
| 152 | } | ||
| 153 | |||
| 150 | #endif | 154 | #endif |
test/parsec.zig+21-2| ... | @@ -315,12 +315,11 @@ pub fn addCases(cases: &tests.ParseCContext) { | ... | @@ -315,12 +315,11 @@ pub fn addCases(cases: &tests.ParseCContext) { |
| 315 | \\pub const LUA_GLOBALSINDEX = -10002; | 315 | \\pub const LUA_GLOBALSINDEX = -10002; |
| 316 | ); | 316 | ); |
| 317 | 317 | ||
| 318 | cases.add("sift right assign", | 318 | cases.add("shift right assign", |
| 319 | \\int log2(unsigned a) { | 319 | \\int log2(unsigned a) { |
| 320 | \\ int i = 0; | 320 | \\ int i = 0; |
| 321 | \\ while (a > 0) { | 321 | \\ while (a > 0) { |
| 322 | \\ a >>= 1; | 322 | \\ a >>= 1; |
| 323 | \\ //i++; | ||
| 324 | \\ } | 323 | \\ } |
| 325 | \\ return i; | 324 | \\ return i; |
| 326 | \\} | 325 | \\} |
| ... | @@ -334,4 +333,24 @@ pub fn addCases(cases: &tests.ParseCContext) { | ... | @@ -334,4 +333,24 @@ pub fn addCases(cases: &tests.ParseCContext) { |
| 334 | \\ return i; | 333 | \\ return i; |
| 335 | \\} | 334 | \\} |
| 336 | ); | 335 | ); |
| 336 | |||
| 337 | cases.add("shift right assign with a fixed size type", | ||
| 338 | \\#include <stdint.h> | ||
| 339 | \\int log2(uint32_t a) { | ||
| 340 | \\ int i = 0; | ||
| 341 | \\ while (a > 0) { | ||
| 342 | \\ a >>= 1; | ||
| 343 | \\ } | ||
| 344 | \\ return i; | ||
| 345 | \\} | ||
| 346 | , | ||
| 347 | \\export fn log2(_arg_a: u32) -> c_int { | ||
| 348 | \\ var a = _arg_a; | ||
| 349 | \\ var i: c_int = 0; | ||
| 350 | \\ while (a > c_uint(0)) { | ||
| 351 | \\ a >>= u5(1); | ||
| 352 | \\ }; | ||
| 353 | \\ return i; | ||
| 354 | \\} | ||
| 355 | ); | ||
| 337 | } | 356 | } |