void test_floor_log2() { /* floorlog2() */ assert(floor_log2(16)==4); assert(floor_log2(1)==0); assert(floor_log2(((bitboard)1<<63)==64)); }
void WaveformBlockFilter:: test() { // It should update a block with cwt transform data. { Timer t; // Tfr::DrawnWaveform waveformdesc; // Signal::Interval data = waveformdesc.requiredInterval (Signal::Interval(0,4), 0); Signal::Interval data(0,4); // Create some data to plot into the block Signal::pMonoBuffer buffer(new Signal::MonoBuffer(data, data.count ()/4)); float *p = buffer->waveform_data()->getCpuMemory (); srand(0); for (unsigned i=0; i<buffer->getInterval ().count (); ++i) { p[i] = -1.f + 2.f*rand()/RAND_MAX; } // Create a block to plot into BlockLayout bl(4,4, buffer->sample_rate ()); VisualizationParams::ptr vp(new VisualizationParams); Reference ref = [&]() { Reference ref; Position max_sample_size; max_sample_size.time = 2.f*max(1.f, buffer->length ())/bl.texels_per_row (); max_sample_size.scale = 1.f/bl.texels_per_column (); ref.log2_samples_size = Reference::Scale( floor_log2( max_sample_size.time ), floor_log2( max_sample_size.scale )); ref.block_index = Reference::Index(0,0); return ref; }(); Heightmap::pBlock block( new Heightmap::Block(ref, bl, vp)); // Create some data to plot into the block Tfr::ChunkAndInverse cai; cai.input = buffer; // Do the merge Heightmap::MergeChunk::ptr mc( new WaveformBlockFilter ); Update::IUpdateJob::ptr job = mc->prepareUpdate (cai)[0]; EXCEPTION_ASSERT(dynamic_cast<WaveformBlockUpdater::Job*>(job.get ())); std::queue<Heightmap::Update::UpdateQueue::Job> jobs; Heightmap::Update::UpdateQueue::Job j; j.updatejob = job; j.intersecting_blocks = vector<pBlock>{block}; jobs.push (std::move(j)); WaveformBlockUpdater().processJobs(jobs); float T = t.elapsed (); EXCEPTION_ASSERT_LESS(T, 1.0); // this is ridiculously slow } }
/* --------------------------------------------------------------------------------------- void pawn_double_moves(CHESS_STATE *current_state) purpose: adds any pawn double moves --------------------------------------------------------------------------------------- */ inline void pawn_double_moves(CHESS_STATE *current_state, bitboard empty_squares) { /* Pawn Single Moves */ COLOR_ENUM color = (current_state->flg_is_white_move ? BB_WHITE : BB_BLACK); int pawn_direction = (color==BB_WHITE) ? 1 : -1; bitboard start_mask = (color==BB_WHITE) ? PAWN_START_WHITE : PAWN_START_BLACK; bitboard pawn_moves = current_state->boards[color + BB_PAWN] & start_mask; pawn_moves = MOVE_UP_COUNT(pawn_moves,pawn_direction) & empty_squares; pawn_moves = MOVE_UP_COUNT(pawn_moves,pawn_direction) & empty_squares; bitboard pawn; while((pawn = get_lowest_bit(&pawn_moves))!=0) { CHESS_STATE *new_state = insert_child( current_state, BB_PAWN, MOVE_DOWN_COUNT(pawn,2*pawn_direction) | pawn, EMPTY_BOARD); // when pawn moves double - exposes to possible en passant if (new_state != NULL) { new_state->flg_is_enpassant = 1; new_state->flg_enpassant_file = COL(floor_log2(pawn)); } } }
/* Select the Pivot Element . Strategy 1: Select a random sample of size O(logN) from the array and compute median log to base 2 N is a good sampling choice as it scales well for smaller and larger data sets alike */ int select_pivot(int low_idx, int high_idx) { int i = 0; int N = floor_log2(high_idx - low_idx + 1); int *random_indexes = calloc(N, sizeof(int)); // array double *random_elements = calloc(N, sizeof(double)); // array double final_median = 0; srand(time(NULL)); // Seed the RNG for (i = 0; i < N; i++) { random_indexes[i] = rand() % (high_idx - low_idx + 1) + low_idx; random_elements[i] = buf[random_indexes[i]]; } final_median = (median_low(random_elements, N) + median_high(random_elements, N)) / 2; // Free allocated memory free(random_indexes); free(random_elements); return final_median; }
int exact_log2 (unsigned HOST_WIDE_INT x) { if (x != (x & -x)) return -1; return floor_log2 (x); }
/* Returns floor(log(n)/log(sqrt(2))). Undefined if N is 0. */ static size_t calculate_h_alpha (size_t n) { size_t log2 = floor_log2 (n); /* The correct answer is either 2 * log2 or one more. So we see if n >= pow(sqrt(2), 2 * log2 + 1) and if so, add 1. */ return (2 * log2) + (n >= pow_sqrt2 (log2)); }
static void test_floor_log2(void) { assert(floor_log2(1) == 0); assert(floor_log2(2) == 1); assert(floor_log2(3) == 1); assert(floor_log2(4) == 2); assert(floor_log2(6) == 2); assert(floor_log2(134) == 7); }
void restore_func_cl_pf_opts_mapping (tree func) { PTR *slot; struct func_cl_pf_opts_mapping map, *entry; /* This will be the case for languages whose FEs don't call record_func_cl_pf_opts_mapping. */ if (!func_cl_pf_opts_mapping_hash_table) return; map.func = func; slot = htab_find_slot (func_cl_pf_opts_mapping_hash_table, &map, INSERT); if (*slot) entry = *slot; else { /* This means we did not call record_func_cl_opts_pf_mapping earlier. Currently this happens for functions defined inside a C++ class; we just record a token stream for those, which doesn't include pragmas in a usable fashion. For now just use the command line options for these. */ entry = xmalloc (sizeof (struct func_cl_pf_opts_mapping)); entry->func = func; entry->cl_pf_opts = &cl_pf_opts_cooked; *slot = entry; } cl_pf_opts = *(entry->cl_pf_opts); /* APPLE LOCAL begin 4760857 optimization pragmas */ /* The variables set here are dependent on the per-func flags, but do not have corresponding command line options, so can't be saved and restored themselves in the current mechanism. So just (re)compute them. */ align_loops_log = floor_log2 (align_loops * 2 - 1); align_jumps_log = floor_log2 (align_jumps * 2 - 1); align_labels_log = floor_log2 (align_labels * 2 - 1); if (align_labels_max_skip > align_labels || !align_labels) align_labels_max_skip = align_labels - 1; /* APPLE LOCAL end 4760857 optimization pragmas */ }
/* Converts the vine rooted at *Q, which contains exactly COUNT nodes, into a balanced tree, and updates *Q to point to the new root of the balanced tree. */ static void vine_to_tree (struct Node **q, size_t count) { size_t leaf_nodes = count + 1 - ((size_t) 1 << floor_log2 (count + 1)); size_t vine_nodes = count - leaf_nodes; compress (q, leaf_nodes); while (vine_nodes > 1) { vine_nodes /= 2; compress (q, vine_nodes); } while ((*q)->down[0] != NULL) { (*q)->down[0]->up = *q; q = &(*q)->down[0]; } }
// Returns a pointer to an opaque structure of FFT tables. n must be a power of 2 and n >= 4. void *fft_init(size_t n) { // Check size argument if (n < 4 || n > UINT64_MAX || (n & (n - 1)) != 0) return NULL; // Error: Size is too small or is not a power of 2 if (n - 4 > SIZE_MAX / sizeof(double) / 2 || n > SIZE_MAX / sizeof(size_t)) return NULL; // Error: Size is too large, which makes memory allocation impossible // Allocate structure struct FftTables *tables = malloc(sizeof(struct FftTables)); if (tables == NULL) return NULL; tables->n = n; // Allocate arrays tables->bit_reversed = malloc(n * sizeof(size_t)); tables->trig_tables = malloc((n - 4) * 2 * sizeof(double)); if (tables->bit_reversed == NULL || tables->trig_tables == NULL) { free(tables->bit_reversed); free(tables->trig_tables); free(tables); return NULL; } // Precompute bit reversal table int levels = floor_log2(n); uint64_t i; for (i = 0; i < n; i++) tables->bit_reversed[i] = reverse_bits(i, levels); // Precompute the packed trigonometric table for each FFT internal level uint64_t size; uint64_t k = 0; for (size = 8; size <= n; size *= 2) { for (i = 0; i < size / 2; i += 4) { uint64_t j; for (j = 0; j < 4; j++, k++) tables->trig_tables[k] = accurate_sine(i + j + size / 4, size); // Cosine for (j = 0; j < 4; j++, k++) tables->trig_tables[k] = accurate_sine(i + j, size); // Sine } if (size == n) break; } return tables; }
int omp_max_vf (void) { if (!optimize || optimize_debug || !flag_tree_loop_optimize || (!flag_tree_loop_vectorize && (global_options_set.x_flag_tree_loop_vectorize || global_options_set.x_flag_tree_vectorize))) return 1; int vf = 1; int vs = targetm.vectorize.autovectorize_vector_sizes (); if (vs) vf = 1 << floor_log2 (vs); else { machine_mode vqimode = targetm.vectorize.preferred_simd_mode (QImode); if (GET_MODE_CLASS (vqimode) == MODE_VECTOR_INT) vf = GET_MODE_NUNITS (vqimode); } return vf; }
int ffs_hwi (unsigned HOST_WIDE_INT x) { return 1 + floor_log2 (x & -x); }
/* --------------------------------------------------------------------------------------- char *get_move(CHESS_STATE *current_state, int ui_flag) purpose: gets the movetext for a chess state Notes: if ui_flag!=0, the MoveTextUI string is returned. This routine checks all bitboards. Move is valid if: 1. Maximum of 1 piece moves 2. Exception to #1 above is castling 3. Maximum of 1 piece removed The full move is either normal text or UI text normal text, eg xe3 (pawn captures piece at e3) UI text , eg d2:e3 e3:P (black pawn captures white pawn at e3) when ui_text==0, the standard algebraic chess notation for the move is returned. This is the abbreviated form UNLESS an explicit representation is required, in order of: 1. specific rank qualifier 2. specific row qualifier 3. specific exact starting square Special treatment required for: 1. en passant moves --------------------------------------------------------------------------------------- */ char *get_move(CHESS_STATE *current_state, int ui_flag) { // full move char *move = malloc(20 * sizeof (char)); memset(move,0,20); char from_str[3] = {0}; char to_str[3] = {0}; char captured_str[2] = {0}; char enpassant_suffix[5]={0}; int number_moved = 0; // number of pieces moved - normally = 1 int number_captured = 0; // number of pieces captured - <=1 int number_friendly_captured = 0; // pawn promotion int number_new = 0; // number of new pieces (pawn promotion) int captured_piece = 0; // captured piece index int friendly_captured_piece = 0; // the pawn 'removed' int moved_piece=0; // moving piece index int new_piece=0; // the new piece (normally queen for promoted pawn) int explicit_row = 0; // flags to denote explicit move text int explicit_col = 0; // flags to denote explicit move text CHESS_STATE* parent = current_state->parent; // the color of the moving piece is the 'parent' move. // the current state is the 'position' after the move, where // the other piece has become the active color. COLOR_ENUM bb_color = (parent->flg_is_white_move) ? BB_WHITE : BB_BLACK; int i; for (i=0; i<BB_COUNT; i++) { if (parent->boards[i] != current_state->boards[i]) { bitboard delta = (parent->boards[i])^ (current_state->boards[i]); bitboard from = parent->boards[i] & delta; bitboard to = current_state->boards[i] & delta; if (bit_count(to) == bit_count(from)) { // moved number_moved += bit_count(to); if (number_moved > 1) { printf("Too may pieces Moved !"); abort(); } moved_piece=i; // at this point, see if any other moves from same // parent state involve the same piece type moving // to the same finishing square CHESS_STATE *other_states; for (other_states = current_state->parent->child_head; other_states!=NULL; other_states=other_states->next) { if (other_states!=current_state) { //see if other state shares similar move: bitboard other_delta = (parent->boards[i])^ (other_states->boards[i]); bitboard other_from = parent->boards[i] & other_delta; bitboard other_to = current_state->boards[i] & other_delta; if (other_to==to && other_from != from) // other move cannot start from same square ! { // another move DOES share the same finishing square explicit_row += ((ROW(floor_log2(from))==(ROW(floor_log2(other_from))))); explicit_col += ((COL(floor_log2(from))==(COL(floor_log2(other_from))))); } } } // special treatment #1 (en passant) if (moved_piece-bb_color==BB_PAWN && parent->flg_is_enpassant==1 && to == (parent->flg_enpassant_file + (bb_color==BB_WHITE?A6:A3))) { explicit_col += 1; strcpy(enpassant_suffix,"e.p."); } strcpy(from_str,get_square_text(floor_log2(from))); strcpy(to_str,get_square_text(floor_log2(to))); } else if (bit_count(from)>0 && i != (bb_color+BB_PAWN)) { // captured (opponents only) - excluding pawn promotion number_captured += bit_count(from); if (number_captured > 1) { printf("more than one piece captured"); exit(1); } captured_piece=i; strcpy(captured_str,"x"); } else if (bit_count(from) > 0) { // friendly pawn removed for pawn promotion number_friendly_captured += bit_count(from); if (number_friendly_captured > 1) { printf("more than one friendly piece captured"); exit(1); } friendly_captured_piece = i; strcpy(from_str,get_square_text(floor_log2(from))); } else if (bit_count(to) > 0) { // pawn_promotion number_new += bit_count(to); if (number_new > 1) { printf("more than one new piece"); exit(1); } new_piece = i; strcpy(to_str,get_square_text(floor_log2(to))); } } } // 1. piece moving (normal text) if (ui_flag==0 && moved_piece % 6 != BB_PAWN) move[0] = piece_chr[moved_piece]; // 2. from square if (ui_flag!=0) strcat(move,from_str); else { if (explicit_col!=0) strncat(move,&from_str[0],1); if (explicit_row!=0) strncat(move,&from_str[1],1); } // 3. capture string or ':' if (ui_flag==0) if (number_captured>0) strcat(move, captured_str); else {} else { strcat(move, ":"); } // 4. to square strcat(move,to_str); // 5. en passant suffix if (ui_flag==0) strcat(move,enpassant_suffix); // 6. piece to delete (UI text only) if (ui_flag!=0 && number_captured>0) { strcat(move," "); strcat(move,to_str); strcat(move,":"); move[strlen(move)] = piece_chr[captured_piece]; } // 7. pawn promotion if (ui_flag==0 && number_new > 0) { move[strlen(move)] = piece_chr[new_piece]; } if (ui_flag!=0 && number_new > 0) { // pawn strcat(move," "); strcat(move,from_str); strcat(move,":"); move[strlen(move)] = piece_chr[friendly_captured_piece]; //queen strcat(move," "); strcat(move,to_str); strcat(move,":"); move[strlen(move)] = piece_chr[new_piece]; } return move; }
/* ---------------------------------------------------------- CHESS_STATE set_piece_placement(char *piece_placement_string) purpose: sets the chess state piece_placement (bitboards) from the piece placement string. ---------------------------------------------------------- */ CHESS_STATE set_piece_placement(char *piece_placement_string) { char *delim_slash = "/"; // delimiter char *next_row = NULL; // holds value of each row int row_start; row_start = floor_log2(A8); char* pps = malloc(100 * sizeof (char)); // copy the string passed in, to an internal field // just in case the function argument is a literal, // as strtok can't work on literals. strcpy(pps, piece_placement_string); CHESS_STATE cs = {0}; next_row = strtok(pps, delim_slash); while(next_row != NULL) { int col=0; int row=0; char next_char; while((next_char = next_row[row++]) != '\0') { switch(next_char) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': col+=(next_char-'0'); case 'p': case 'r': case 'n': case 'b': case 'q': case 'k': case 'P': case 'R': case 'N': case 'B': case 'Q': case 'K': { int i; for (i=0; i<BB_COUNT; i++) { if (piece_chr[i] == next_char) { cs.boards[i] |= ((bitboard)1<<row_start+col); ++col; cs.board_value += piece_values[i]; break; } } } } } if (col!=8) {exit(1);} // each row should add up to 8 row_start=row_start-8 ; // drop down one line row=0; next_row = strtok(NULL, delim_slash); } if (row_start!= -8) { printf("Error in set_piece_placement"); exit(1); } free(pps); return cs; }
int ctz_hwi (unsigned HOST_WIDE_INT x) { return x ? floor_log2 (x & -x) : HOST_BITS_PER_WIDE_INT; }
int ceil_log2 (unsigned HOST_WIDE_INT x) { return floor_log2 (x - 1) + 1; }
static void test_exact_log2(void) { assert(floor_log2(1) == 0); assert(floor_log2(2) == 1); assert(floor_log2(4) == 2); assert(floor_log2(256) == 8); }
inline std::size_t ceil_log2 (std::size_t x) { return static_cast<std::size_t>((x & (x-1)) != 0) + floor_log2(x); }
inline std::size_t floor_log2 (std::size_t x) { const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT; return floor_log2(x, integer<std::size_t, Bits>()); }
/***************************************************** * Thread function that will attempt to sort locally */ void *parallel_qsort(void *arg_struct) { int st_idx, en_idx, rc; double median = 0; struct thread_data index_left, index_right; void *status; pthread_t first_thread; pthread_t second_thread; /* * Extract the thread args from the structure passed in */ struct thread_data *args; args = (struct thread_data *) arg_struct; st_idx = args->st_idx; en_idx = args->en_idx; if (en_idx > st_idx) { int N = en_idx - st_idx + 1; // Get number of // elements in // this array if (floor_log2(thread_count) < MAXDEPTH && N > floor_log2(MAXLEN)) { // If /* * 1. Pivot Selection Strategy */ median = select_pivot(st_idx, en_idx); // printf("Median chosen ---> %ld\n", median); /* * 2. Partition the data into subarrays lesser and greater * than pivot */ int pivot_index = partition_new(st_idx, en_idx, median); // partition_new( /* * Update the thread counter */ pthread_mutex_lock(&mutexthread); /* Lock Mutex */ thread_count += 2; ++real_thread_count; pthread_mutex_unlock(&mutexthread); /* Unlock Mutex */ /* * Fire the thread to sort the lesser than sub-array */ index_left.st_idx = st_idx; index_left.en_idx = pivot_index - 1; /* * Re-use current thread to sort the greater array ... so no * new thread creation */ index_right.st_idx = pivot_index + 1; index_right.en_idx = en_idx; // printf("****** Parallel Sorting now (%d,%d) and (%d,%d) N = // %d depth = %d\n", st_idx, pivot_index - 1, pivot_index + 1, // en_idx, N, floor_log2( thread_count ) ); /* * Now we have called a new thread to sort the lesser array */ rc = pthread_create(&first_thread, NULL, parallel_qsort, (void *) &index_left); rc = pthread_create(&second_thread, NULL, parallel_qsort, (void *) &index_right); pthread_join(first_thread, NULL); pthread_join(second_thread, NULL); } else { // printf("****** Serial Sorting now (%d,%d) N = %d depth = // %d\n", st_idx, en_idx, N, floor_log2( thread_count ) ); serial_quickSort(st_idx, en_idx); // Sort Serially the list } /* * void *pquick(void *arg){ ... pthread_t leftthr,rightthr; ... * * if (right > left){ if (recursionlev<MAXLEVELS) { ... * pthread_create(&leftthr, NULL, pquick, (void *) &leftarg); * pthread_create(&rightthr, NULL, pquick, (void *) &rightarg); * pthread_join(leftthr, NULL); pthread_join(rightthr, NULL); } * else { quicksort(left); // Serial quicksort quicksort(right); } * * } } */ } // End of main if /* * And... EXIT */ pthread_exit(NULL); }
/* Function to emit isr vector section. */ static void nds32_emit_isr_vector_section (int vector_id) { unsigned int vector_number_offset = 0; const char *c_str = "CATEGORY"; const char *sr_str = "SR"; const char *nt_str = "NT"; const char *vs_str = "VS"; char first_level_handler_name[100]; char section_name[100]; char symbol_name[100]; /* Set the vector number offset so that we can calculate the value that user specifies in the attribute. We also prepare the category string for first level handler name. */ switch (nds32_isr_vectors[vector_id].category) { case NDS32_ISR_INTERRUPT: vector_number_offset = 9; c_str = "i"; break; case NDS32_ISR_EXCEPTION: vector_number_offset = 0; c_str = "e"; break; case NDS32_ISR_NONE: case NDS32_ISR_RESET: /* Normally it should not be here. */ gcc_unreachable (); break; } /* Prepare save reg string for first level handler name. */ switch (nds32_isr_vectors[vector_id].save_reg) { case NDS32_SAVE_ALL: sr_str = "sa"; break; case NDS32_PARTIAL_SAVE: sr_str = "ps"; break; } /* Prepare nested type string for first level handler name. */ switch (nds32_isr_vectors[vector_id].nested_type) { case NDS32_NESTED: nt_str = "ns"; break; case NDS32_NOT_NESTED: nt_str = "nn"; break; case NDS32_NESTED_READY: nt_str = "nr"; break; } /* Currently we have 4-byte or 16-byte size for each vector. If it is 4-byte, the first level handler name has suffix string "_4b". */ vs_str = (nds32_isr_vector_size == 4) ? "_4b" : ""; /* Now we can create first level handler name. */ snprintf (first_level_handler_name, sizeof (first_level_handler_name), "_nds32_%s_%s_%s%s", c_str, sr_str, nt_str, vs_str); /* Prepare vector section and symbol name. */ snprintf (section_name, sizeof (section_name), ".nds32_vector.%02d", vector_id); snprintf (symbol_name, sizeof (symbol_name), "_nds32_vector_%02d%s", vector_id, vs_str); /* Everything is ready. We can start emit vector section content. */ nds32_emit_section_head_template (section_name, symbol_name, floor_log2 (nds32_isr_vector_size), false); /* According to the vector size, the instructions in the vector section may be different. */ if (nds32_isr_vector_size == 4) { /* This block is for 4-byte vector size. Hardware $VID support is necessary and only one instruction is needed in vector section. */ fprintf (asm_out_file, "\tj\t%s ! jump to first level handler\n", first_level_handler_name); } else { /* This block is for 16-byte vector size. There is NO hardware $VID so that we need several instructions such as pushing GPRs and preparing software vid at vector section. For pushing GPRs, there are four variations for 16-byte vector content and we have to handle each combination. For preparing software vid, note that the vid need to be substracted vector_number_offset. */ if (TARGET_REDUCED_REGS) { if (nds32_isr_vectors[vector_id].save_reg == NDS32_SAVE_ALL) { /* Case of reduced set registers and save_all attribute. */ fprintf (asm_out_file, "\t! reduced set regs + save_all\n"); fprintf (asm_out_file, "\tsmw.adm\t$r15, [$sp], $r15, 0xf\n"); fprintf (asm_out_file, "\tsmw.adm\t$r0, [$sp], $r10, 0x0\n"); } else { /* Case of reduced set registers and partial_save attribute. */ fprintf (asm_out_file, "\t! reduced set regs + partial_save\n"); fprintf (asm_out_file, "\tsmw.adm\t$r15, [$sp], $r15, 0x2\n"); fprintf (asm_out_file, "\tsmw.adm\t$r0, [$sp], $r5, 0x0\n"); } } else { if (nds32_isr_vectors[vector_id].save_reg == NDS32_SAVE_ALL) { /* Case of full set registers and save_all attribute. */ fprintf (asm_out_file, "\t! full set regs + save_all\n"); fprintf (asm_out_file, "\tsmw.adm\t$r0, [$sp], $r27, 0xf\n"); } else { /* Case of full set registers and partial_save attribute. */ fprintf (asm_out_file, "\t! full set regs + partial_save\n"); fprintf (asm_out_file, "\tsmw.adm\t$r15, [$sp], $r27, 0x2\n"); fprintf (asm_out_file, "\tsmw.adm\t$r0, [$sp], $r5, 0x0\n"); } } fprintf (asm_out_file, "\tmovi\t$r0, %d ! preparing software vid\n", vector_id - vector_number_offset); fprintf (asm_out_file, "\tj\t%s ! jump to first level handler\n", first_level_handler_name); } nds32_emit_section_tail_template (symbol_name); }
int clz_hwi (unsigned HOST_WIDE_INT x) { return HOST_BITS_PER_WIDE_INT - 1 - floor_log2 (x); }
/* Function to emit isr reset handler content. Including all jmptbl/vector references, jmptbl section, vector section, nmi handler section, and warm handler section. */ static void nds32_emit_isr_reset_content (void) { unsigned int i; unsigned int total_n_vectors; const char *vs_str; char reset_handler_name[100]; char section_name[100]; char symbol_name[100]; total_n_vectors = nds32_isr_vectors[0].total_n_vectors; vs_str = (nds32_isr_vector_size == 4) ? "_4b" : ""; fprintf (asm_out_file, "\t! RESET HANDLER CONTENT - BEGIN !\n"); /* Create references in .rodata according to total number of vectors. */ fprintf (asm_out_file, "\t.section\t.rodata\n"); fprintf (asm_out_file, "\t.align\t2\n"); /* Emit jmptbl references. */ fprintf (asm_out_file, "\t ! references to jmptbl section entries\n"); for (i = 0; i < total_n_vectors; i++) fprintf (asm_out_file, "\t.word\t_nds32_jmptbl_%02d\n", i); /* Emit vector references. */ fprintf (asm_out_file, "\t ! references to vector section entries\n"); for (i = 0; i < total_n_vectors; i++) fprintf (asm_out_file, "\t.word\t_nds32_vector_%02d%s\n", i, vs_str); /* Emit jmptbl_00 section. */ snprintf (section_name, sizeof (section_name), ".nds32_jmptbl.00"); snprintf (symbol_name, sizeof (symbol_name), "_nds32_jmptbl_00"); fprintf (asm_out_file, "\t! ....................................\n"); nds32_emit_section_head_template (section_name, symbol_name, 2, true); fprintf (asm_out_file, "\t.word\t%s\n", nds32_isr_vectors[0].func_name); nds32_emit_section_tail_template (symbol_name); /* Emit vector_00 section. */ snprintf (section_name, sizeof (section_name), ".nds32_vector.00"); snprintf (symbol_name, sizeof (symbol_name), "_nds32_vector_00%s", vs_str); snprintf (reset_handler_name, sizeof (reset_handler_name), "_nds32_reset%s", vs_str); fprintf (asm_out_file, "\t! ....................................\n"); nds32_emit_section_head_template (section_name, symbol_name, floor_log2 (nds32_isr_vector_size), false); fprintf (asm_out_file, "\tj\t%s ! jump to reset handler\n", reset_handler_name); nds32_emit_section_tail_template (symbol_name); /* Emit nmi handler section. */ snprintf (section_name, sizeof (section_name), ".nds32_nmih"); snprintf (symbol_name, sizeof (symbol_name), "_nds32_nmih"); fprintf (asm_out_file, "\t! ....................................\n"); nds32_emit_section_head_template (section_name, symbol_name, 2, true); fprintf (asm_out_file, "\t.word\t%s\n", (strlen (nds32_isr_vectors[0].nmi_name) == 0) ? "0" : nds32_isr_vectors[0].nmi_name); nds32_emit_section_tail_template (symbol_name); /* Emit warm handler section. */ snprintf (section_name, sizeof (section_name), ".nds32_wrh"); snprintf (symbol_name, sizeof (symbol_name), "_nds32_wrh"); fprintf (asm_out_file, "\t! ....................................\n"); nds32_emit_section_head_template (section_name, symbol_name, 2, true); fprintf (asm_out_file, "\t.word\t%s\n", (strlen (nds32_isr_vectors[0].warm_name) == 0) ? "0" : nds32_isr_vectors[0].warm_name); nds32_emit_section_tail_template (symbol_name); fprintf (asm_out_file, "\t! RESET HANDLER CONTENT - END !\n"); }
/* * Estimate selectivity of "column @> const" and "column && const" based on * most common element statistics. This estimation assumes element * occurrences are independent. * * mcelem (of length nmcelem) and numbers (of length nnumbers) are from * the array column's MCELEM statistics slot, or are NULL/0 if stats are * not available. array_data (of length nitems) is the constant's elements. * * Both the mcelem and array_data arrays are assumed presorted according * to the element type's cmpfunc. Null elements are not present. * * TODO: this estimate probably could be improved by using the distinct * elements count histogram. For example, excepting the special case of * "column @> '{}'", we can multiply the calculated selectivity by the * fraction of nonempty arrays in the column. */ static Selectivity mcelem_array_contain_overlap_selec(Datum *mcelem, int nmcelem, float4 *numbers, int nnumbers, Datum *array_data, int nitems, Oid operator, FmgrInfo *cmpfunc) { Selectivity selec, elem_selec; int mcelem_index, i; bool use_bsearch; float4 minfreq; /* * There should be three more Numbers than Values, because the last three * cells should hold minimal and maximal frequency among the non-null * elements, and then the frequency of null elements. Ignore the Numbers * if not right. */ if (nnumbers != nmcelem + 3) { numbers = NULL; nnumbers = 0; } if (numbers) { /* Grab the lowest observed frequency */ minfreq = numbers[nmcelem]; } else { /* Without statistics make some default assumptions */ minfreq = 2 * (float4) DEFAULT_CONTAIN_SEL; } /* Decide whether it is faster to use binary search or not. */ if (nitems * floor_log2((uint32) nmcelem) < nmcelem + nitems) use_bsearch = true; else use_bsearch = false; if (operator == OID_ARRAY_CONTAINS_OP) { /* * Initial selectivity for "column @> const" query is 1.0, and it will * be decreased with each element of constant array. */ selec = 1.0; } else { /* * Initial selectivity for "column && const" query is 0.0, and it will * be increased with each element of constant array. */ selec = 0.0; } /* Scan mcelem and array in parallel. */ mcelem_index = 0; for (i = 0; i < nitems; i++) { bool match = false; /* Ignore any duplicates in the array data. */ if (i > 0 && element_compare(&array_data[i - 1], &array_data[i], cmpfunc) == 0) continue; /* Find the smallest MCELEM >= this array item. */ if (use_bsearch) { match = find_next_mcelem(mcelem, nmcelem, array_data[i], &mcelem_index, cmpfunc); } else { while (mcelem_index < nmcelem) { int cmp = element_compare(&mcelem[mcelem_index], &array_data[i], cmpfunc); if (cmp < 0) mcelem_index++; else { if (cmp == 0) match = true; /* mcelem is found */ break; } } } if (match && numbers) { /* MCELEM matches the array item; use its frequency. */ elem_selec = numbers[mcelem_index]; mcelem_index++; } else { /* * The element is not in MCELEM. Punt, but assume that the * selectivity cannot be more than minfreq / 2. */ elem_selec = Min(DEFAULT_CONTAIN_SEL, minfreq / 2); } /* * Update overall selectivity using the current element's selectivity * and an assumption of element occurrence independence. */ if (operator == OID_ARRAY_CONTAINS_OP) selec *= elem_selec; else selec = selec + elem_selec - selec * elem_selec; /* Clamp intermediate results to stay sane despite roundoff error */ CLAMP_PROBABILITY(selec); } return selec; }
/* ---------------------------------------------------------- char *get_piece_placement(CHESS_STATE chess_state) purpose: gets the piece placement string from a CHESS_STATE. ---------------------------------------------------------- */ char *get_piece_placement(CHESS_STATE chess_state) { char squares[64] = {0}; int index=0; int blanks=0; char last_square = '\0'; char* piece_placement_string = malloc(100 * sizeof (char)); int i; for (i=0; i<BB_COUNT; i++) { bitboard next_board = chess_state.boards[i]; bitboard next_bit; while((next_bit=get_lowest_bit(&next_board))!=0) squares[floor_log2(next_bit)]=piece_chr[i]; } int row_start = floor_log2(A8); // starting point int col = 0; for (row_start = 56; row_start >= 0; row_start-=8) { for (col = 0; col < 8; col++) { if ((squares[row_start+col] != last_square) && (blanks > 0)) { piece_placement_string[index++] = '0' + blanks; // number of blank squares blanks = 0; } switch(squares[row_start+col]) { case '\0': // blank square ++blanks; break; default: // square has piece on. piece_placement_string[index++] = squares[row_start+col]; blanks = 0; // reset blanks } last_square=squares[row_start+col]; } // end of row if (blanks > 0) { piece_placement_string[index++] = '0' + blanks; // number of blank squares blanks = 0; } if (row_start != 0) piece_placement_string[index++] = '/'; // new line blanks = 0; last_square = '\0'; } piece_placement_string[index] = '\0'; // null terminator return piece_placement_string; }