2
.section .note.GNU-stack, "", @progbits
7
.type dv_decode_vlc,@function
12
/* Args are at bits=rdi, maxbit=rsi, result=rdx */
13
mov %rdi,%rax /* %rax is bits */
14
mov %rsi,%rbx /* %rbx is maxbits */
15
and $0x3f,%rbx /* limit index range STL*/
17
/* note that BITS is left aligned */
18
/* klass = dv_vlc_classes[maxbits][(bits & (dv_vlc_class_index_mask[maxbits])) >> */
19
/* (dv_vlc_class_index_rshift[maxbits])]; */
21
mov dv_vlc_class_index_mask@GOTPCREL(%rip),%r11 /* use %rip for PIC code */
22
mov (%r11,%rbx,4),%ebp /* int32 */ /* dv_vlc_class_index_mask[maxbits] */
23
and %eax,%ebp /* bits & */
24
mov dv_vlc_class_index_rshift@GOTPCREL(%rip),%rcx
25
mov (%rcx,%rbx,4),%ecx /* int32 */ /* dv_vlc_class_index_rshift[maxbits] */
27
mov dv_vlc_classes@GOTPCREL(%rip),%rcx
28
mov (%rcx,%rbx,8),%rcx /* ptr */ /* dv_vlc_classes[maxbits], a pointer */
29
movsbq (%rcx,%rbp,1),%rbp /* int8 */ /* klass = */
31
/* *result = dv_vlc_lookups[klass][(bits & (dv_vlc_index_mask[klass])) >> */
32
/* (dv_vlc_index_rshift[klass])]; */
34
mov dv_vlc_index_mask@GOTPCREL(%rip),%r11
35
mov (%r11,%rbp,4),%ebx /* int32 */ /* (dv_vlc_index_mask[klass]) */
37
mov dv_vlc_index_rshift@GOTPCREL(%rip),%r11
38
mov (%r11,%rbp,4),%ecx /* int32 */ /* dv_vlc_index_rshift[klass] */
39
and %eax,%ebx /* bits & */
42
mov dv_vlc_lookups@GOTPCREL(%rip),%r11
43
mov (%r11,%rbp,8),%rbp /* ptr */ /* dv_vlc_lookups[klass] */
44
mov (%rbp,%rbx,4),%ebp /* int32 */ /* *result = */
46
/* Now %ebp holds result, a dv_vlc_t, like this:
51
/* code needs to do this with result:
52
if ((result->lamp > 0) &&
53
if (bits & sign_mask[result->len])
54
result->lamp = -result->lamp;
58
/* Form a mask from (bits & sign_mask[result->len]) */
61
and $0xff,%ecx /* result->len */
62
mov sign_mask@GOTPCREL(%rip),%rbx
63
mov (%rbx,%rcx,4),%ebx /* int32 */
69
sar $31,%ebx /* result->amp */
75
/* Now %eax is 0xffff0000 if we want to negate %ebp, zero otherwise */
80
if (maxbits < result->len)
82
Note that the 'broken' pattern is all ones (i.e. 0xffffffff)
84
mov %esi,%ebx /* maxbits */ /* int32 */
89
mov %ebp,(%rdx) /* *result = */
97
void __dv_decode_vlc(int bits, dv_vlc_t *result)
102
.globl __dv_decode_vlc
103
.type __dv_decode_vlc,@function
108
/* Args are bits=rdi, result=rsi */
109
mov %rdi,%rax /* %rax is bits */
114
mov dv_vlc_class_lookup5@GOTPCREL(%rip),%r11
115
movsbq (%r11,%rbp),%rbp /* int8 klass */
117
mov dv_vlc_index_mask@GOTPCREL(%rip),%rbx
118
mov (%rbx,%rbp,4),%ebx /* int32 */
119
mov dv_vlc_index_rshift@GOTPCREL(%rip),%rcx
120
mov (%rcx,%rbp,4),%ecx /* int32 */
122
sar %cl,%ebx /* %rbx is klass */
124
mov dv_vlc_lookups@GOTPCREL(%rip),%r11
125
mov (%r11,%rbp,8),%rbp /* ptr */
126
mov (%rbp,%rbx,4),%ebp /* int32 */
128
/* Now %ebp holds result, like this:
133
/* code needs to do this with result:
134
if ((result->amp > 0) &&
135
if ((bits >> sign_rshift[result->len]) & 1)
136
result->amp = result->-amp;
139
/* if (result->amp < 0) %rbp is 0, else 0xffff0000. */
143
mov sign_mask@GOTPCREL(%rip),%r11
144
mov (%r11,%rcx,4),%ecx /* int32 */
159
mov %ebp,(%rsi) /* *result = */
167
void dv_parse_ac_coeffs_pass0(bitstream_t *bs,
173
.globl dv_parse_ac_coeffs_pass0
174
.type dv_parse_ac_coeffs_pass0,@function
176
dv_parse_ac_coeffs_pass0:
178
/* Args are at rdi=bs, rsi=mb, rdx=bl */
193
mov %rdx,%r15 /* bl */
194
mov %rdi,%r14 /* bs */
195
mov bitstream_t_buf(%r14),%r14 /* bs->buf */
197
mov dv_block_t_offset(%r15),%r13d /* bl->offset */
199
mov dv_block_t_reorder(%r15),%r12 /* bl->reorder */
201
/* I think it would be better to zero out the coeffs as we're
202
copying them into the framebuffer. But that optimization is
205
movq dv_block_t_coeffs(%r15),%mm1
207
pand const_f_0_0_0(%rip),%mm1
208
movq %mm1,dv_block_t_coeffs(%r15) /* bl->coeffs[0] */
210
/* memset(&bl->coeffs[1],'\0',sizeof(bl->coeffs)-sizeof(bl->coeffs[0])); */
211
movq %mm0,(dv_block_t_coeffs + 8)(%r15)
212
movq %mm0,(dv_block_t_coeffs + 16)(%r15)
213
movq %mm0,(dv_block_t_coeffs + 24)(%r15)
214
movq %mm0,(dv_block_t_coeffs + 32)(%r15)
215
movq %mm0,(dv_block_t_coeffs + 40)(%r15)
216
movq %mm0,(dv_block_t_coeffs + 48)(%r15)
217
movq %mm0,(dv_block_t_coeffs + 56)(%r15)
218
movq %mm0,(dv_block_t_coeffs + 64)(%r15)
219
movq %mm0,(dv_block_t_coeffs + 72)(%r15)
220
movq %mm0,(dv_block_t_coeffs + 80)(%r15)
221
movq %mm0,(dv_block_t_coeffs + 88)(%r15)
222
movq %mm0,(dv_block_t_coeffs + 96)(%r15)
223
movq %mm0,(dv_block_t_coeffs + 104)(%r15)
224
movq %mm0,(dv_block_t_coeffs + 112)(%r15)
225
movq %mm0,(dv_block_t_coeffs + 120)(%r15)
228
/* bits = bitstream_show(bs,16); */
229
mov %r13,%rcx /* bl->offset */
230
shr $3,%rcx /* divide by 8 bits/byte */
231
movzbq (%r14,%rcx,1),%rax /* bs->(buf+offset) */
232
movzbq 1(%r14,%rcx,1),%r11 /* bs->(buf+offset+1) */
233
movzbq 2(%r14,%rcx,1),%rcx /* bs->(buf+offset+2) */
237
or %r11,%rax /* rax contains the 3 bitstream bytes */
238
mov %r13,%r11 /* bl->offset */
239
and $7,%r11 /* num_bits = 3 lsb's of bl->offset */
241
sub %r11,%rcx /* 8 - num_bits */
242
shr %cl,%rax /* bits = >> to remove bits already processed */
244
/* bits_left = bl->end - bl->offset; */
245
mov dv_block_t_end(%r15),%r11d
246
sub %r13d,%r11d /* r11 is bits_left */
248
/* if(bits_left < 16) */
252
/* ecx is most significant 7 bits */
257
/* Attempt to use the shortcut first. If it hits, then
258
this vlc term has been decoded. */
259
mov dv_vlc_class1_shortcut@GOTPCREL(%rip),%r10
260
mov (%r10,%rcx,4),%r11d /* record32 dv_vlc_tab_t */
267
/* fast path: use inlined version of __dv_decode_vlc */
268
/* ---------------------- */
269
mov %r12,dv_block_t_reorder(%r15)
273
mov dv_vlc_class_lookup5@GOTPCREL(%rip),%r10
274
movsbq (%r10,%rcx,1),%rcx /* int8 */
277
mov dv_vlc_index_mask@GOTPCREL(%rip),%r10
278
mov (%r10,%rcx,4),%r12d /* int32 */
280
mov dv_vlc_lookups@GOTPCREL(%rip),%r10
281
mov (%r10,%rcx,8),%r11 /* ptr->record32 */
283
mov dv_vlc_index_rshift@GOTPCREL(%rip),%r10
284
mov (%r10,%rcx,4),%ecx /* int32 */
289
mov (%r11,%r12,4),%r11d /* int32 */
291
/* Now %r11 holds result, like this:
296
test $0x80,%r11d /* If (vlc.run < 0) break */
298
/* code needs to do this with result:
300
if ((bits >> sign_rshift[result->len]) & 1)
304
/* if (amp < 0) %r11 is 0, else 0xffff0000. */
309
mov sign_mask@GOTPCREL(%rip),%r10
310
mov (%r10,%rcx,4),%ecx /* int32 */
317
xor $0xffffffff,%r12d
318
and $0xffff0000,%r12d
324
mov dv_block_t_reorder(%r15),%r12 /* ptr */
325
/* ---------------------- */
328
/* bl->offset += vlc.len */
334
/* bl->reorder += vlc.run */
336
mov %r11d,%eax /* int32 */
338
add %rax,%r12 /* ptr */
340
/* SET_COEFF(bl->coeffs, bl->reorder, vlc.amp); */
345
movw %r11w,(dv_block_t_coeffs)(%r15,%rax,1) /* int16 */
350
mov dv_block_t_reorder(%r15),%r12
352
/* if (vlc.amp == 0) */
353
test $0xffff0000,%r11d
355
/* bl->reorder = bl->reorder_sentinel; */
356
mov dv_block_t_reorder_sentinel(%r15),%r12 /* ptr */
357
/* bl->offset += 4; */
360
movl $1,dv_block_t_eob(%r15) /* int32 */
361
/* mb->eob_count++; */
363
incl dv_macroblock_t_eob_count(%r11) /* int32 */
366
/* else if(vlc.len == VLC_ERROR) */
368
and $0x0000ff00,%r11d
369
cmp $0x0000fe00,%r11d /* VLC_ERROR */
371
/* mb->vlc_error = TRUE; */
373
movl $1,dv_macroblock_t_vlc_error(%r11); /* int32 */
375
mov %r12,dv_block_t_reorder(%r15) /* ptr */
376
mov %r13d,dv_block_t_offset(%r15) /* int32 */
386
/* slow path: use dv_decode_vlc */;
387
/* Args are at rdi=bits, rsi=bits_left, rdx=*vlc */
391
mov %r11,%rsi /* bits */
392
mov %rax,%rdi /* bits_left */
393
lea vlc(%rip),%rdx /* *vlc */
394
mov dv_decode_vlc@GOTPCREL(%rip),%r11
401
test $0x80,%r11 /* If (vlc.run < 0) break */
406
show16: /* not used */
411
mov (%r14,%rcx,1),%rax
412
mov 1(%r14,%rcx,1),%rbx
413
mov 2(%r14,%rcx,1),%rcx
425
gint dv_parse_video_segment(dv_videosegment_t *seg, guint quality) {
427
.globl dv_parse_video_segment
428
.type dv_parse_video_segment,@function
429
dv_parse_video_segment:
431
/* Args are at rdi=seg, rsi=quality */
437
mov %rsi,%rax /* quality */
439
test $DV_QUALITY_COLOR,%rax
443
mov %r12d,n_blocks(%rip) /* int32 */
453
mov %rdi,%r12 /* seg */
454
mov dv_videosegment_t_bs(%r12),%r14 /* seg->bs */
455
mov bitstream_t_buf(%r14),%r14 /* seg->bs->t_buf */
456
lea dv_videosegment_t_mb(%r12),%r13 /* seg->mb */
461
mov %eax,m(%rip) /* int32 */
462
mov %ecx,mb_start(%rip) /* int32 */
464
mov %rdi,%r12 /* seg */
466
/* bitstream_seek_set(bs,mb_start+28); */
467
/* mb->qno = bitstream_get(bs,4); */
470
movzbq 3(%r14,%r11,1),%r11
472
movl %r11d,dv_macroblock_t_qno(%r13) /* int32 */
474
/* mb->vlc_error = 0;
475
mb->eob_count = 0; */
477
movl %r11d,dv_macroblock_t_vlc_error(%r13) /* int32 */
478
movl %r11d,dv_macroblock_t_eob_count(%r13) /* int32 */
480
/* mb->i = (seg->i + dv_super_map_vertical[m]) % (seg->isPAL?12:10); */
481
mov dv_super_map_vertical@GOTPCREL(%rip),%r11
482
movl (%r11,%rax,4),%r11d /* int32 */
484
movl dv_videosegment_t_i(%r12),%ecx /* int32 */
489
movl dv_videosegment_t_isPAL(%r12),%ecx /* int32 */
493
shl $5,%rcx /* rcx = (isPAL ? 32 : 0) */
495
add %r11,%rcx /* rcx = offset from mod10 */
496
lea mod_10(%rip),%r11
497
movzbq (%r11,%rcx,1),%r11 /* uses mod_12 for PAL */ /* int8 */
498
movl %r11d,dv_macroblock_t_i(%r13) /* int32 */
500
/* mb->j = dv_super_map_horizontal[m]; */
501
mov dv_super_map_horizontal@GOTPCREL(%rip),%r11
502
movl (%r11,%rax,4),%r11d /* int32 */
503
movl %r11d,dv_macroblock_t_j(%r13) /* int32 */
505
/* mb->k = seg->k; */
506
movl dv_videosegment_t_k(%r12),%r11d /* int32 */
507
movl %r11d,dv_macroblock_t_k(%r13) /* int32 */
509
xor %r12,%r12 /* b=0 */
510
lea dv_macroblock_t_b(%r13),%r15 /* mb->b */
514
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
515
|15 | | | | | | | | 7 | 6 | 5 | 4 | | | | 0 |
516
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
518
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
520
/* dc coefficient = bitstream_get(bs,9); */
521
mov mb_start(%rip),%ecx /* int32 */
523
lea blk_start(%rip),%r11
524
movzbq (%r11,%r12),%r11 /* int8 */
526
movzbq (%r14,%r11,1),%rax /* hi byte */
527
movzbq 1(%r14,%r11,1),%rcx /* lo byte */
529
or %rcx,%rax /* int16 */
532
/* if(dc > 255) dc -= 512;
533
just do an arithmetric shift right 7bits*/
534
sarw $7,%r11w /* dc in %r11, 9 bits */
535
movw %r11w,dv_block_t_coeffs(%r15) /* int16 */
537
/* bl->class_no = bitstream_get(bs,2); */
541
movl %ecx,dv_block_t_class_no(%r15) /* int32 */
545
movl %ecx,dv_block_t_eob(%r15) /* int32 */
547
/* bl->dct_mode = bitstream_get(bs,1); */
550
movl %eax,dv_block_t_dct_mode(%r15) /* int32 */
552
/* bl->reorder = &dv_reorder[bl->dct_mode][1]; */
553
shl $6,%rax /* *64 */
554
mov dv_reorder@GOTPCREL(%rip),%rcx
557
mov %rax,dv_block_t_reorder(%r15) /* ptr */
559
/* bl->reorder_sentinel = bl->reorder + 63; */
561
mov %rax,dv_block_t_reorder_sentinel(%r15) /* ptr */
563
/* bl->offset= mb_start + dv_parse_bit_start[b]; */
565
movl mb_start(%rip),%ecx /* int32 */
566
mov dv_parse_bit_start@GOTPCREL(%rip),%rax
567
mov (%rax,%r12,4),%eax /* int32 */
569
movl %eax,dv_block_t_offset(%r15) /* int32 */
571
/* bl->end= mb_start + dv_parse_bit_end[b]; */
572
mov dv_parse_bit_end@GOTPCREL(%rip),%rax
573
mov (%rax,%r12,4),%eax /* int32 */
575
mov %eax,dv_block_t_end(%r15) /* int32 */
577
/* dv_parse_ac_coeffs_pass0(bs,mb,bl); */
578
mov %rsi,%rcx /* quality */
579
test $DV_QUALITY_AC_MASK,%rcx
582
/* no AC pass. Just zero out the remaining coeffs */
583
movq dv_block_t_coeffs(%r15),%mm1
585
pand const_f_0_0_0(%rip),%mm1
586
movq %mm1,dv_block_t_coeffs(%r15)
587
movq %mm0,(dv_block_t_coeffs + 8)(%r15)
588
movq %mm0,(dv_block_t_coeffs + 16)(%r15)
589
movq %mm0,(dv_block_t_coeffs + 24)(%r15)
590
movq %mm0,(dv_block_t_coeffs + 32)(%r15)
591
movq %mm0,(dv_block_t_coeffs + 40)(%r15)
592
movq %mm0,(dv_block_t_coeffs + 48)(%r15)
593
movq %mm0,(dv_block_t_coeffs + 56)(%r15)
594
movq %mm0,(dv_block_t_coeffs + 64)(%r15)
595
movq %mm0,(dv_block_t_coeffs + 72)(%r15)
596
movq %mm0,(dv_block_t_coeffs + 80)(%r15)
597
movq %mm0,(dv_block_t_coeffs + 88)(%r15)
598
movq %mm0,(dv_block_t_coeffs + 96)(%r15)
599
movq %mm0,(dv_block_t_coeffs + 104)(%r15)
600
movq %mm0,(dv_block_t_coeffs + 112)(%r15)
601
movq %mm0,(dv_block_t_coeffs + 120)(%r15)
605
/* dv_parse_ac_coeffs_pass0(bs,mb,bl); Args are at rdi=bs, rsi=mb, rdx=bl */
609
mov dv_videosegment_t_bs(%rdi),%rdi /* passed in rdi was seg, now passing seg->bs */
610
mov %r13,%rsi /* mb */
611
mov %r15,%rdx /* bl */
612
mov dv_parse_ac_coeffs_pass0@GOTPCREL(%rip),%r11
620
movl n_blocks(%rip),%eax /* int32 */
621
add $dv_block_t_size,%r15 /* point to next block */
626
mov m(%rip),%eax /* int32 */
627
mov mb_start(%rip),%ecx /* int32 */
629
add $dv_macroblock_t_size,%r13 /* point to next macroblock */
641
/* if ((quality & DV_QUALITY_AC_MASK) == DV_QUALITY_AC_2) */
642
mov %rsi,%rax /* quality */
643
and $DV_QUALITY_AC_MASK,%rax
644
cmp $DV_QUALITY_AC_2,%rax
647
mov dv_parse_ac_coeffs@GOTPCREL(%rip),%r11
662
.long 0 /* 4 for monochrome, 6 for color */
664
.byte 4,18,32,46,60,70
666
/* mod tables, 32 bytes apart */
668
.byte 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7
669
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* spacer, see above */
671
.byte 0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7,8