| /* This is a case extracted from CSiBE which would sometimes contain the |
| following sequence: |
| cmp/eq r12,r13 |
| movt r0 |
| xor #1,r0 |
| extu.b r0,r0 |
| movt r3 |
| tst r0,r0 |
| bf/s .L35 |
| where the negated T bit store did not combine properly. Since there are |
| other movt insns and the sequence will try to utilize the 'movt_movrt' |
| patterns, we only check for the extu. */ |
| /* { dg-do compile } */ |
| /* { dg-options "-O2" } */ |
| /* { dg-final { scan-assembler-not "extu" } } */ |
| |
| typedef struct transaction_s transaction_t; |
| |
| struct journal_head |
| { |
| transaction_t * b_transaction; |
| struct journal_head *b_cpnext, *b_cpprev; |
| }; |
| |
| struct transaction_s |
| { |
| struct journal_head * t_checkpoint_list; |
| transaction_t *t_cpnext, *t_cpprev; |
| }; |
| |
| struct journal_s |
| { |
| transaction_t * j_checkpoint_transactions; |
| unsigned long j_first, j_last; |
| }; |
| |
| typedef struct journal_s journal_t; |
| |
| extern int __try_to_free_cp_buf (struct journal_head *jh); |
| extern int __cleanup_transaction (journal_t *journal, transaction_t *transaction); |
| extern void __flush_batch (void **bhs, int *batch_count); |
| extern void* jh2bh (void*); |
| |
| static int |
| __flush_buffer (journal_t *journal, struct journal_head *jh, |
| void **bhs, int *batch_count, int *drop_count) |
| { |
| void *bh = jh2bh (jh); |
| int ret = 0; |
| if (bh) |
| { |
| bhs[*batch_count] = bh; |
| (*batch_count)++; |
| if (*batch_count == 64) |
| ret = 1; |
| } |
| else |
| { |
| int last_buffer = 0; |
| if (jh->b_cpnext == jh) |
| last_buffer = 1; |
| if (__try_to_free_cp_buf (jh)) |
| { |
| (*drop_count)++; |
| ret = last_buffer; |
| } |
| } |
| return ret; |
| } |
| |
| int |
| log_do_checkpoint (journal_t *journal, int nblocks) |
| { |
| transaction_t *transaction, *last_transaction, *next_transaction; |
| int batch_count = 0; |
| void *bhs[64]; |
| |
| repeat: |
| transaction = journal->j_checkpoint_transactions; |
| if (transaction == ((void *)0)) |
| return 0; |
| last_transaction = transaction->t_cpprev; |
| next_transaction = transaction; |
| do |
| { |
| struct journal_head *jh, *last_jh, *next_jh; |
| int drop_count = 0; |
| int cleanup_ret, retry = 0; |
| transaction = next_transaction; |
| next_transaction = transaction->t_cpnext; |
| jh = transaction->t_checkpoint_list; |
| last_jh = jh->b_cpprev; |
| next_jh = jh; |
| do |
| { |
| jh = next_jh; |
| next_jh = jh->b_cpnext; |
| retry = __flush_buffer(journal, jh, bhs, &batch_count, &drop_count); |
| } while (jh != last_jh && !retry); |
| |
| if (retry) |
| goto repeat; |
| |
| cleanup_ret = __cleanup_transaction(journal, transaction); |
| goto repeat; |
| } while (transaction != last_transaction); |
| } |